← Cloud & DevOps
Cloud & DevOps

Serverless Is Not What You Think — A Brutally Honest Assessment

⚙️

Serverless computing was supposed to be the end of infrastructure management. Deploy a function, pay only for what you use, never think about servers again. The reality, five years into widespread adoption, is more complicated — and more interesting.

What serverless actually means

When you deploy an AWS Lambda function or a Vercel Edge Function, there are absolutely servers running your code — you just don't manage them. The "serverless" label means you don't provision, patch, or scale servers. You pay per-invocation rather than for always-on capacity. The operational burden genuinely shifts: you're not managing infrastructure, but you are managing a very different kind of complexity.

Where serverless genuinely shines

Event-driven workloads — image processing triggered by uploads, webhook handlers, scheduled jobs, API backends with spiky traffic — are natural fits. For these, serverless delivers on its promise: near-zero idle costs, automatic scaling, and dramatically reduced ops overhead.

The cold start problem

Serverless functions that haven't been invoked recently need to "spin up" — loading your runtime, dependencies, and code. This cold start latency (anywhere from 100ms to several seconds depending on the runtime and function size) is unacceptable for user-facing applications requiring consistent sub-100ms responses. Workarounds exist (provisioned concurrency on Lambda, keeping functions warm), but they erode the cost benefits.

The hidden complexity

Distributed tracing, observability, managing shared state without a persistent server, and debugging production functions are genuinely harder in serverless environments. The operational complexity doesn't disappear — it shifts from infrastructure management to application architecture. Teams without strong software engineering foundations often find this trade worse, not better.

The execution model and its implications

In serverless, your code runs in ephemeral containers that are created on demand and destroyed after execution. You write functions — discrete pieces of logic — and the platform handles everything else: provisioning compute, scaling to zero when idle, scaling to thousands of instances when traffic spikes, and charging only for the milliseconds of actual execution time.

This execution model has profound implications for how you architect applications. You cannot maintain in-memory state between invocations (each execution is independent). You cannot hold long-running connections. You need to externalise state to databases, caches, or message queues. These constraints force architectures that are inherently scalable and fault-tolerant — which is often a feature, not a limitation.

Cold starts: the primary performance challenge

The most discussed drawback of serverless is the cold start — the latency introduced when a function is invoked after being idle, requiring the platform to provision a new container and load your code. Cold start times vary from milliseconds (for simple Node.js or Python functions) to several seconds (for large Java or .NET functions with heavy dependencies).

For latency-sensitive applications — user-facing APIs where response time matters — cold starts can be a genuine problem. The mitigations include choosing lightweight runtimes, keeping functions small and focused, using provisioned concurrency (paying to keep a pool of warm instances), and architectural patterns that route latency-sensitive traffic away from cold-start-prone code paths.

The event-driven architecture fit

Serverless functions shine brightest in event-driven architectures — where code executes in response to events like a file upload, a database write, a message queue entry, or an HTTP request. This is where the economics are most compelling: an image processing pipeline that resizes photos when uploaded to S3 might process 10,000 images per day or zero, and serverless pricing reflects exactly that variable load without requiring you to provision for peak.

Major cloud providers have built rich ecosystems of event sources that integrate natively with serverless functions — S3 triggers, DynamoDB streams, API Gateway routes, SNS notifications, and dozens more. Building data processing pipelines, webhook handlers, scheduled tasks, and backend microservices with these integrations is often dramatically simpler than equivalent containerised architectures.

Cost at scale: the inflection point

Serverless pricing is genuinely economical at low and variable load, but there is an inflection point at high, consistent load where reserved compute becomes cheaper. If your function runs continuously at high throughput, you're paying for the convenience of serverless without benefiting from its core economic advantage — paying only for what you use.

The pragmatic approach adopted by most mature engineering organisations is hybrid: serverless for event-driven, variable, or infrequent workloads; containerised or VM-based compute for high-throughput, latency-sensitive, or continuously running services. The tools are not mutually exclusive, and good architecture uses each where it provides the best operational and economic fit.

More ArticlesAll topics →
🧠
How Large Language Models Actually Work — No PhD Required
From tokens to transformers, a plain-English breakdown of what's happening inside every AI assistant you use.
8 minJune 12, 2025
AI Agents Are Here — And They're Already Doing Your Job
From booking flights to writing code autonomously, AI agents are crossing a threshold that changes everything.
7 minJune 5, 2025
🔐
Why Your Password Manager Can Still Get Hacked
Understanding the real attack surfaces and what you should actually do about it.
5 minJune 10, 2025