Part 8 · 1 chapters · ~8 min
Pairing Tables by Runtime
The usual production stack for Node, Python, Go, Rust, Rails, Java, .NET and Elixir at one service, ten services and a hundred, with the reason each pairing exists.
11
What each runtime is paired with
| runtime | 1 service | 10 services | 100 services |
|---|---|---|---|
| Node | Fastify/Express on a PaaS, Postgres, Redis | containers, BullMQ, PgBouncer, OTel SDK, Nginx/ALB | Kubernetes, Kafka, mesh sidecars, API gateway, Vault |
| Python | Django + Gunicorn + Nginx, Postgres, Celery + Redis | Uvicorn/ASGI, PgBouncer, Celery beat, Sentry, OTel | Kubernetes, Kafka, RabbitMQ, mesh, Vault |
| Go | one binary, systemd or a PaaS, Postgres | containers, gRPC, Prometheus, NATS or Redis | Kubernetes, Envoy/Istio, Kafka, Consul or k8s discovery |
| Rust | Axum binary behind Caddy | containers, Tokio tuning, OTel, Redis | often the hot-path service inside a Go or Java platform |
| Rails | Puma + Nginx (or Kamal), Postgres, Solid Queue or Sidekiq | PgBouncer, Redis, Sidekiq, Sentry, CDN for assets | Kubernetes, Kafka, modular monolith split into services slowly |
| Java | Spring Boot fat jar, Postgres, HikariCP | Spring Cloud Config, Eureka or k8s, Kafka, Micrometer, OTel agent | Kubernetes, Istio sidecars, Kafka, Vault, Quarkus native for small services |
| .NET | ASP.NET Core on Kestrel behind a proxy, SQL Server or Postgres | containers, MassTransit + RabbitMQ, OTel | Kubernetes, Azure Service Bus, Dapr or a mesh |
| Elixir | Phoenix release, Postgres, Oban | libcluster for BEAM clustering, Phoenix PubSub | Kubernetes, Kafka via Broadway; fewer external pieces needed |
Each pairing exists to cover a weakness: Python and Ruby need app servers and workers because of the GIL/GVL and their request models; the JVM's heavy startup pushes toward fewer, larger instances (or native images); Go's single binary needs little; Elixir's BEAM provides supervision and clustering that other stacks buy from infrastructure.