Cold Starts Are a Pricing Decision, Not a Performance Bug
Scale-to-zero is not a property of your platform. It is a dial, and leaving it at the default means someone else decided what your slowest request costs.

Cold Starts Are a Pricing Decision ❄️
Somewhere in every serverless migration there is an afternoon spent trying to make the first request fast. Trim the image. Lazy-load the heavy module. Move the database client out of the module scope. All of this is real work with real gains, and all of it is optimizing the wrong variable.
The first request is slow because nothing was running. That is not a performance bug. It is the behavior you asked for when you accepted scale-to-zero, and it has a price attached that you can simply pay.
What you are actually trading
Scale-to-zero says: when nobody is using this, it costs nothing, and the person who wakes it up pays for the startup.
That is a genuinely good trade for a lot of workloads. Internal tools. Staging. A webhook that fires nine times a day. Anything where the users are you, or where a two-second first response is invisible because the request is a background one.
It is a bad trade for the front page of a product. Not because two seconds is unbearable, but because of who pays it. The person absorbing your cold start is disproportionately a first-time visitor arriving from a link — the traffic you spent the most to get, evaluating you on the least information. The cost is real and it lands in the worst possible place.
Do the arithmetic before the optimization
The useful move is not to make startup fast. It is to find out what keeping one instance warm actually costs, because the number is often absurdly small next to the effort of optimizing around it.
Roughly:
warm baseline ≈ (instance memory × instance count) × hourly rate × 730
For a small service with one always-warm instance, this frequently lands in single-digit dollars per month. Compare that against the afternoon you were about to spend restructuring module imports — and against the visitors who close the tab.
The reason this arithmetic gets skipped is that "min instances = 0" is the default, and defaults do not feel like decisions. But it is exactly a decision, and it is being made on your behalf by whoever wrote the template.
When optimizing the cold start is still right
Paying to stay warm does not eliminate cold starts, it only makes them rarer. Traffic spikes still recruit new instances, and those instances still start cold. So the startup path deserves attention — just not panicked attention.
The changes with real leverage, in order:
- Do not connect to anything at module scope. A database or cache client constructed at import time makes every cold start wait for a handshake, including the ones during a spike when the dependency is already struggling.
- Ship a smaller image. Pull time is part of start time. This is where multi-stage builds and trimmed output formats pay for themselves twice — once in registry cost, once in latency.
- Defer the heavy import to the route that needs it. If one rarely-used endpoint drags in an enormous dependency, every cold start pays for it.
- Set concurrency deliberately. How many simultaneous requests one instance handles determines how often you recruit a new one. Too low and you cold-start constantly under mild load; too high and one slow request blocks its neighbors.
Note that none of these get you to zero. They shrink the tail. The dial removes it for the common case.
The framing worth keeping
Infrastructure defaults are opinions with a bill attached. Scale-to-zero, request concurrency, instance limits, log retention — each one is a knob where someone picked a sensible-for-somebody value, and none of them announce themselves as choices.
The habit that pays off is small: for each default you have inherited, be able to say in one sentence what it costs you and what changing it would cost. Not to change all of them. Just to know, so that the next time a slow first request sends you toward a day of module surgery, you can check whether the answer is a config line and five dollars.