The ladderRung 3 of 8outline, full version in progress
Rung 3 — Containers + microservices
One line: Split the app along team lines so teams stop waiting on each other. Not before you have teams.
Concept. You leave Rung 2 because the monolith has become a queue: several teams change one codebase, one deploy carries everyone's risk, and a slow or failing module drags down the rest. Containers make each piece deployable on its own; services draw the boundaries. This rung is about organisational scaling first and technical scaling second — Conway's law applied on purpose. Many businesses never need it; a single team should skip to Rung 4.
Signs you are here. Business: two or more product teams; release calendars; "we can't ship X until Y finishes"; an outage in one feature took the whole app down. Technical: Dockerfiles; a container platform (ECS, Cloud Run, Kubernetes); several services with their own repos or folders; an API gateway; service-to-service auth; the first distributed-systems bug (a request that half-succeeded).
The decision. How to split — by business capability (orders, catalogue, billing), never by technical layer. How far — start with two or three services carved from the monolith, not twenty. Where to run — a managed container service (Cloud Run, ECS Fargate, Fly.io) before Kubernetes; Kubernetes only when the team can staff it. Shared database or per-service database — per-service is the goal, shared is the honest starting point, and the migration between them is the hard part of this rung.
Tools. Containers: Docker. Managed runtime: Google Cloud Run, AWS ECS Fargate, Fly.io, Railway. Kubernetes when justified: EKS / GKE / AKS. API gateway: Kong, AWS API Gateway, Cloud Endpoints. Service communication: REST first, gRPC when latency matters, a queue (SQS, Pub/Sub, RabbitMQ) for anything that can be async. Infra as code becomes mandatory: Terraform or Pulumi. CI/CD: GitHub Actions. Observability: OpenTelemetry into Grafana / Datadog / Honeycomb.
Next trigger. Toward Rung 4: reporting queries hit service databases and slow them; the owner wants numbers across services and nobody can join them. Toward Rung 5: services poll each other for changes; "did the order ship?" is answered by a cron job that checks every minute.
Threads. Security: service identity (mTLS or signed tokens), a secrets manager, network policy — zero trust starts here in earnest. Compliance: SOC 2 becomes realistic; scope which services touch regulated data and isolate them. Data modeling: each service owns its schema; cross-service facts are copied via events, not joined — eventual consistency is the new normal. Cost: idle containers and over-provisioned clusters are the first waste; per-service databases multiply the base bill; tagging by service is how you find out.
[k3r war-story slot: the split that went too far, and the shared-database migration]