POST
Containers vs serverless: the honest tradeoff
Jul 20266 MIN READ
Every architecture discussion eventually reaches the same fork: containers or serverless. The two camps talk past each other, and both are right about the other's weaknesses. Containers are described as overhead by the serverless crowd. Serverless is described as a trap by the container crowd. The truth is that they are different tools with different economics, and the right choice depends on the shape of your traffic, your tolerance for operational work, and your willingness to deal with the failure modes of each.
I have run services both ways, and the teams that make the choice well are the ones that ask the right questions before they pick a side. The questions are not about what is trendy. They are about what your traffic actually does, who is around to operate the system, and what happens when things go wrong.
Containers: the control you pay for
Containers give you a runtime you control. Your image ships with the exact dependencies, the exact operating system libraries, the exact environment, and it runs the same way everywhere, from a developer laptop to a production cluster. The predictability is the whole pitch, and it is real. The container that passed the tests is the container that runs in production, byte for byte.
The price is the operations. Someone has to run the cluster, manage the nodes, handle the scaling, patch the host operating system, and decide what happens when a node dies. Managed Kubernetes takes care of some of this, and it leaves you with the rest: the autoscaling configuration, the resource requests and limits, the rollout strategy, the persistent volumes, the networking. The team that runs containers is a team with a second job, and the job is the platform.
The economics of containers favor steady, predictable traffic. The cost is roughly flat whether you use one instance or are idle, because you are paying for the capacity, not the usage. If your service has a baseline load that never goes to zero, containers are the efficient choice, because the idle capacity is doing real work.
Serverless: the scale you did not ask for
Serverless inverts the economics. You pay for what you run, not for the capacity you reserve. The service that runs twice a day costs almost nothing. The service that spikes to ten thousand requests has the capacity automatically, and the bill reflects the spike, not a guess about it.
The price is a different kind of operational work: the cold start, the request timeout, the platform constraints, and the debugging that happens across a platform you do not control. The cold start is the famous one: a function that has not run in a while needs to initialize, and the user waits. The teams that get burned by this are the ones that assume the cold start does not exist, and the teams that avoid it are the ones that design for it, with warmers, or with a runtime that keeps the functions hot, or by accepting the latency for low traffic paths.
The economics favor spiky, bursty, or unpredictable traffic. The service that has no baseline, or a baseline that is dwarfed by its peaks, is the service that serverless handles efficiently, because the idle periods cost nothing. The service with steady traffic is the one where serverless is a tax: you pay per request for work that a container would do at a flat rate.
The failure modes are the real comparison
The honest comparison is not the happy path. It is the failure modes, and they are different. The container failure mode is the node that dies, the cluster that misbehaves, the platform you have to operate in the middle of the night. The serverless failure mode is the platform doing something you cannot see, the cold start you cannot tune, the timeout that kills a slow request, the vendor making a change that breaks your assumptions.
The debugging story is the part people underestimate. A container is a machine you can inspect: ssh in, look at the logs, run a command, poke at the state. A serverless function is a black box that ran somewhere, and the debugging is done through logs and traces, and the logs had better be good, because there is no ssh. The teams that run serverless successfully are the ones that invest in observability first, because they have no other way to see what is happening.
The concurrency story is also different. Containers handle concurrency by scaling the instances, and the scale is limited by the cluster. Serverless handles concurrency by scaling the functions, and the scale is effectively unbounded, which is great until it is not: the runaway loop that would exhaust a cluster instead spends a budget, and the bill is the safety valve.
The shape of the traffic decides
The question that settles the debate in practice is the shape of the traffic. Steady, predictable, always on: containers, because the capacity is cheap and the control is useful. Spiky, bursty, unpredictable, with long idle periods: serverless, because the idle time is free and the scaling is automatic.
The second question is the shape of the work. Short requests that fit the platform limits: serverless is fine. Long running jobs, streaming, stateful work, anything that needs a connection held open or a process that lives: containers, because serverless will time out on it or hold it hostage.
The third question is the team. Is there someone who wants to run a platform, who will be on call for the cluster, who enjoys the operational craft? If yes, containers are a feature. If the team is small and the operations budget is thin, the managed platform of serverless is a feature, and the constraints are the price.
The hybrid is not a compromise
The answer is often both, and it is not a hedge. The steady core service runs on containers, and the bursty spikey job runs on serverless. The batch job that runs nightly on a schedule runs on serverless, and the long lived connection server runs on containers. The boundary is drawn by the shape of each workload, not by a religious commitment.
The hybrid has its own cost, which is that the team now operates two platforms and knows two sets of failure modes. The justification is the workloads genuinely differ. If every workload has the same shape, the hybrid is just doubling the operations work, and the team should pick the one platform that fits and accept its tradeoffs.
The honest summary
Containers and serverless are not good and evil. They are two ways of paying for compute, one where you pay for capacity and control the runtime, one where you pay for usage and accept the platform's constraints. The right choice is a function of traffic shape, workload shape, and team appetite for operations. The wrong choice is the one made on hype, because hype does not pay the bill and does not take the pager calls.
Ask the shape questions before you build. The answer will be boring, and the boring answer is usually the right one.