I've watched serverless go through the hype cycle, and by 2021 it's settled into something genuinely useful. The use cases where it genuinely improves on container-based architectures are well understood; so are the failure modes.

The event-driven sweet spot

Serverless functions (Lambda, Azure Functions, Google Cloud Functions) are optimal for event-driven, stateless, intermittent workloads: processing uploaded files, responding to queue messages, handling webhook callbacks, scheduled batch jobs. The pay-per-invocation pricing, automatic scaling to zero, and elimination of idle capacity costs make serverless dramatically more economical than containers for these patterns.

Cold start as the constraint

Cold start latency, the initialisation time when a function handles its first request after a period of inactivity, is the primary technical limitation of serverless. For .NET and JVM runtimes, cold start can add hundreds of milliseconds to the first response. Strategies: provisioned concurrency (keep functions warm at a cost), use a lightweight runtime (Node.js, Python have lower cold start than .NET/Java historically), or design user flows that tolerate the first-hit latency.

The distributed systems complexity

A serverless architecture that decomposes a workflow into many small functions connected by queues and event buses has all the failure modes of a distributed system without the stateful recovery mechanisms of a long-running service. Idempotency is essential: every function must handle re-delivery of the same event. Distributed tracing across function boundaries requires structured trace context propagation. Dead letter queues must be monitored and processed.

When to choose containers instead

Long-running background workloads, applications with sub-100ms cold start requirements for all requests, workloads that need persistent in-memory state, and workloads with predictable high throughput are better served by containers. The economics of serverless invert at sustained high throughput: a container running continuously at capacity is cheaper than paying per-invocation for the same volume.