Serverless vs containers: the three questions that decide it
The serverless-vs-containers debate is religious in a lot of teams. It does not need to be. Three workload characteristics determine the right answer, and you can answer them in an afternoon.
1. What is the request shape?
Serverless excels at spiky, low-baseline workloads. A webhook receiver that handles ten requests an hour and occasionally spikes to ten thousand is a textbook fit. You pay nothing in idle time and the platform handles the scale-out.
Containers excel at sustained, predictable workloads. A service that handles a thousand requests per minute around the clock is cheaper and faster on Fargate or Cloud Run than on Lambda, by a wide margin once you factor in cold starts and per-invocation pricing.
2. What is the latency tolerance?
Cold starts on serverless platforms have improved dramatically — Lambda SnapStart, provisioned concurrency, and the like — but they have not disappeared. If a meaningful fraction of your requests need sub-200ms tail latency, you will be fighting cold starts and provisioned-concurrency budgets every quarter. Containers give you predictable warm latency for less operational effort.
3. What does the runtime need?
Long-running connections, websockets, large in-memory state, custom runtimes, GPU access — all of these push you toward containers. Short-lived, stateless, HTTP request-response — serverless is great.
The honest middle ground
The architecture we ship most often is a hybrid. The core API runs on containers because the load is steady and the latency profile matters. The webhook receivers, the scheduled jobs, the image processing pipeline, and the occasional admin tool run on serverless because they are spiky and the operational simplicity is a real win.
This pattern is not exotic and not novel. It just requires you to stop treating the choice as ideological and start treating it as a workload-by-workload decision.
The decision is reversible
Both platforms are containers under the hood. A well-factored service can move from Lambda to Fargate or from Cloud Run to GKE in a sprint or two if the workload changes character. Don't agonise on day 1. Make a defensible choice for the workload in front of you, and revisit when the workload changes.