Case study · 2025
Splitting a serverless monolith
One Serverless Framework stack with 25+ functions, 5–15 minute deploys and a 500-resource ceiling in sight. Serverless Compose, a long-lived infrastructure stack and container-image handlers brought deploys down to 2–3 minutes per stack.
Context
The Python serverless repo had grown into one Serverless Framework stack: 25+ functions, one EventBridge rule routing six event types into a 600-line monolithic Lambda, and infrastructure resources defined alongside the functions that changed daily.
The problem
Deploys took 5–15 minutes, one bad function blocked all of them, and the stack was approaching CloudFormation’s 500-resource limit. Every change to a handler redeployed the queues and tables it depended on, which is exactly the wrong blast radius.
What I did
- Introduced Serverless Compose to orchestrate several stacks with explicit dependencies.
- Split out a long-lived infrastructure stack — DynamoDB, EventBridge, SQS with dead-letter queues, KMS — deployed rarely and protected from accidental deletion.
- Moved the six event handlers into their own stack as container-image functions, each with its own EventBridge rule, alarms and dashboard.
- Routed events with Pydantic discriminated unions and Powertools, with pytest and Moto for tests that run locally in the same image.
The trade-off
Container images versus ZIP + layers: a 10 GB limit instead of 250 MB, deterministic builds, docker run parity — at the cost of a Dockerfile per stack and slightly more to keep in sync.
Outcome
Per-stack deploys of about 2–3 minutes instead of 5–15, failure contained to one stack, and the tag-and-release workflow unchanged. The infrastructure stack deploys when the infrastructure changes, which is rarely.
What I’d do differently
Separate infrastructure from functions on day one. The resource limit arrives sooner than it looks.