← Work

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.

Period
2025
Stack
  • Python
  • AWS Lambda
  • Lambda container images
  • Serverless Framework
  • Serverless Compose
  • EventBridge
  • SQS
  • DynamoDB
  • KMS
  • Docker
  • Lambda Powertools
  • Pydantic v2
  • pytest + Moto

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.