Polyglot by intent: Node.js and Python for velocity, Go for performance, Java for enterprise integration, PostgreSQL and Kafka underneath.
Our backend stack is polyglot by intent, we select the language and framework appropriate to each workload rather than applying a single stack to every problem. Node.js for high-concurrency API layers, Python for AI and data workloads, Go for performance-critical services, and Java or Spring Boot where enterprise integration and long-term maintenance are the priority.
Node.js and Python cover the majority of our API and AI workloads, with Go brought in for services where sub-millisecond latency and efficient resource use are hard requirements. Java and Spring Boot remain the standard for enterprise integration work, and we work in Rust, .NET, and Elixir when a client's existing infrastructure or performance profile calls for it.
FastAPI and NestJS are our defaults for Python and Node.js API layers, both giving us strong typing, auto-generated documentation, and high throughput out of the box. REST with OpenAPI documentation is our standard for external-facing APIs, gRPC handles internal service-to-service communication where schema validation and latency matter, and GraphQL comes in for products where client-driven query flexibility is worth the added complexity.
Apache Kafka is our default for event-driven systems that need durable, high-throughput message streaming between services, and RabbitMQ handles simpler task-queue patterns well. Cloud-native options like AWS SQS/SNS, Google Pub/Sub, and Azure Service Bus come into play when a client is already committed to a specific cloud provider's ecosystem.
PostgreSQL is our default relational database, chosen for its reliability, its extension ecosystem including pgvector for AI workloads, and its operational maturity. Managed services like Amazon RDS/Aurora, Google Cloud SQL, and Azure SQL Database handle the operational overhead, and CockroachDB or PlanetScale come in when a project needs distributed, horizontally scalable SQL.
MongoDB covers document-oriented workloads, DynamoDB and Firestore handle serverless and mobile-backend use cases well, and Redis is our standard for caching, session management, and rate limiting wherever sub-millisecond response times matter. ClickHouse and TimescaleDB come in for analytics and time-series workloads that a general-purpose database isn't built for.
Auth0, Keycloak, and AWS Cognito cover most of our authentication needs depending on a client's infrastructure, all built on OAuth 2.0, OIDC, and JWT standards. HashiCorp Vault manages secrets so API keys and credentials never end up in code or environment files, and Clerk or Firebase Auth handle lighter-weight, product-embedded authentication flows.
Node.js and Python for velocity, Go where sub-millisecond latency is a hard requirement, Java for enterprise integration.
OpenAPI documentation for external APIs, gRPC for internal services, GraphQL where client-driven flexibility is worth it.
Documentation, versioning, and rate limiting from the first release, not added after the first incident.
For Python and Node.js API layers respectively, both with strong typing, auto-documentation, and high throughput
For performance-critical services where sub-millisecond latency and efficient resource utilisation are requirements
As the default relational database for its reliability, extension ecosystem including pgvector for AI, and operational maturity
For event-driven architectures requiring durable, high-throughput message streaming between services
For caching, session management, rate limiting, and pub/sub patterns with sub-millisecond response requirements
For internal microservice communication where schema enforcement and performance matter more than HTTP/JSON flexibility