Serverless is one of the most effective ideas infrastructure has produced in the last decade. It removes idle capacity, shortens time to first deployment, and lets small teams ship useful systems without arguing about kernels, instance families, or patch windows. For bursty workloads, event-driven jobs, prototypes, and internal glue code, it is often a fantastic choice.
But I do not trust it for critical workloads.
That sounds contrarian because serverless is marketed as the natural end state of infrastructure progress: no servers to manage, automatic scale, built-in resilience, and billing that tracks demand. In the abstract, it is beautiful. In the real world of latency budgets, incident response, compliance, attack surfaces, and ugly edge cases, the abstraction leaks exactly where critical systems can least afford surprises.
When the workload matters to revenue, uptime, reputation, or security, I care less about how elegant the abstraction looks on a slide and more about whether I can predict its behavior under stress. That is where my trust starts to erode.
The core problem is not technology. It is control.
Most infrastructure debates are really arguments about where you want certainty and where you are willing to accept convenience. Serverless pushes hard toward convenience. You offload provisioning, scaling behavior, patching, and much of the operational surface area to a platform. In exchange, you lose direct control over execution environment, performance characteristics, network behavior, and often even the debugging path during an incident.
For non-critical systems, that trade can be excellent. For critical systems, it creates a dangerous asymmetry: your customer still experiences your service as a single promise, but under the hood your operational leverage has been outsourced to a black box.
That is a fine deal right up until the day you need to answer a simple question under pressure: What exactly is the platform doing right now?
In my experience, the hardest outages are not the ones caused by obvious component failure. They are the ones caused by partial degradation inside abstractions that were supposed to make complexity disappear. Serverless often moves failure from the visible layer to the invisible one. It reduces toil on good days and reduces clarity on bad ones.
Cold starts are not the real issue
People love to debate cold starts because they are easy to understand. Yes, they matter. If your service is latency-sensitive, unpredictable startup penalties are a real problem. But cold starts are only the most visible symptom of a deeper issue: performance variance you do not own.
Critical workloads live and die by tail latency, not average latency. Your dashboard can show an acceptable median while the 95th and 99th percentile are quietly destroying user trust. A payment flow, security decision engine, bot mitigation layer, session validator, or API gateway path does not get judged on average performance. It gets judged on the worst moments users actually feel.
With serverless, performance variance comes from places you cannot tune deeply enough:
- Container or runtime warmup behavior you do not fully control
- Shared substrate contention you cannot inspect
- Opaque scaling heuristics during sudden concurrency spikes
- Network path variability between managed services
- Provider-side throttling that appears only under stress
When the workload is critical, variance is the enemy. I would rather run a boring, well-understood service on dedicated compute with slightly lower theoretical efficiency than stake a hard SLO on invisible heuristics.
Elasticity is useful. Predictability is better.
The strongest argument for serverless is elasticity. Why provision for peak if the platform can scale for you? That logic works beautifully for asynchronous or spiky demand. It is less convincing for systems that are always hot, always important, and always expected to respond within narrow boundaries.
A critical workload usually has one or more of the following properties:
- It sits directly in the request path
- It must maintain low and stable latency
- It participates in security decisions
- It has compliance or data locality constraints
- It requires deterministic rollback and debuggability
- Its failure cascades into many downstream systems
In those conditions, predictable capacity beats magical elasticity more often than people admit. The real job of infrastructure is not to scale in the abstract. It is to make behavior legible. If I know the workload profile, I want to pin capacity close to the problem, keep the execution path short, and reduce the number of unknown control loops between request and response.
Serverless is optimized for convenience under variable demand. Critical infrastructure is optimized for confidence under non-ideal conditions. Those are not the same design goals.
Incidents punish abstraction debt
Every architecture accumulates debt. In traditional systems, the debt is often operational: patching, provisioning, capacity planning, and misconfiguration. In serverless systems, the debt is usually abstraction debt. You save time upfront by not managing machines, but you create hidden dependencies on provider behavior, managed service coupling, and platform-specific failure modes.
The bill arrives during incidents.
When something breaks in a VM-based system, I can usually inspect the host, pin traffic, isolate nodes, capture state, shape the network, and create a narrow blast radius. My toolbox is boring, but it is mine.
When something breaks in a serverless stack, too often the incident playbook becomes interpretive art. Logs are fragmented. Traces are incomplete. Retry behavior amplifies load. One managed service quietly rate-limits another. An event backlog grows faster than your dashboards update. The failure is real, but the platform presents it as a statistics problem instead of a systems problem.
That is not a comfortable place to be when customers are waiting and revenue is at stake.
Critical workloads need graceful degradation, not platform optimism
One of my strongest infrastructure beliefs is that every critical system should degrade intentionally. It should fail in layers, not collapse all at once. It should preserve the most important user paths and sacrifice lower-value features first.
That requires architectural discipline:
- Clear priority lanes
- Circuit breakers
- Cached fallbacks
- Queue control
- Rate limiting close to ingress
- Deliberate separation between critical and non-critical compute
Serverless can absolutely participate in this strategy, but it rarely encourages it. The platform narrative is: just decompose into functions and let the runtime handle scale. That mindset leads teams to over-fragment systems that should remain cohesive and to trust platform elasticity where they should be designing backpressure and recovery.
Critical workloads do not need optimistic architecture. They need survivable architecture.
Security and compliance do not disappear inside a function
There is also a security illusion around serverless. Because you do not manage the server, people subconsciously assume part of the risk disappeared. Some of it did. A smaller host-management burden is real. But the attack surface does not vanish; it shifts.
In serverless-heavy systems, risk often grows in these areas:
- Excessive IAM permissions between functions and services
- Event-driven privilege chains that are hard to reason about
- Secret sprawl across managed integrations
- Data egress paths hidden inside platform defaults
- Observability blind spots that slow containment
For security-critical workloads, I want short trust boundaries and explicit execution paths. I want to know where decisions are made, where credentials live, and how fast I can quarantine behavior if something turns malicious. The more a platform turns execution into an invisible fabric, the more discipline you need to rebuild that clarity on top.
Most teams do not rebuild it. They inherit the abstraction and call it simplicity.
Cost becomes unpredictable in the worst possible way
Serverless is often sold as cost-efficient because you only pay for usage. That is directionally true for intermittent demand. For critical always-on systems, it is more complicated. Once traffic is steady, the economics often stop looking elegant. You start paying a premium for convenience, inter-service chatter, data transfer, logging, and the sheer multiplication effect of decomposed execution.
Worse, the bill tends to become least predictable during abnormal traffic, which is exactly when critical systems are most exposed. A noisy event storm, retry cascade, or malicious request pattern can turn into a financial side effect before it becomes a dashboard alert. That is not just a budgeting issue. It is an operational issue.
Infrastructure should not surprise you twice-first technically, then financially.
My rule: use serverless at the edges, not at the heart
I am not anti-serverless. I am anti-misplacement.
Serverless is excellent for glue code, scheduled jobs, event enrichment, administrative automations, lightweight APIs, and burst handling around the edges of a system. It is a powerful accelerant when failure is containable and latency variance is acceptable.
But at the heart of a critical workload-where request paths are hot, consequences are immediate, and recovery must be deterministic-I want boring infrastructure. Long-lived processes. Known capacity. Tight observability. Clear rollback paths. Fewer moving parts. Smaller blast radius. More operational truth.
That is not nostalgia for servers. It is respect for responsibility.
The deeper lesson
Every generation of infrastructure promises to make the old trade-offs disappear. They never disappear. They just move.
Serverless moved toil upward and hidden dependency downward. That is progress for many use cases. It is the wrong optimization for the workloads that define customer trust.
If the service is peripheral, optimize for speed of iteration. If the service is existential, optimize for predictability, recoverability, and control. The platform that saves you time on Tuesday can steal your leverage on the worst Friday of the quarter.
Critical systems are not where I want the cleanest demo. They are where I want the clearest failure mode.
That is why, for critical workloads, I still trust the boring VM.
Follow the journey
Subscribe to Lynk for daily insights on AI strategy, cybersecurity, and building in the age of AI.
Subscribe →