"Serverless" is an attractive option: you are freed from infrastructure management and pay only for what you use. In practice, though, while the effort of managing infrastructure goes down, you have to face constraints and complexity that are specific to application design.
Here is a summary of why serverless is not "the right answer for everyone," the main constraints behind that, and what they imply about where it fits and where it doesn't.
Main Constraints of Serverless
When adopting serverless (FaaS in particular), there are several practical constraints you cannot avoid.
1. Execution model constraints
Serverless is a model built on the assumption of "short-lived, event-driven" work.
- Execution time limits: There is an upper bound, such as the 15 minutes of AWS Lambda. It is not suited to heavy processing that exceeds this.
- No long-running processes: Instances are discarded once processing finishes, so you cannot keep a process running in the background all the time.
- Stateless by assumption: Contents of local memory and disk are not retained across requests. All state must be kept in an external database or storage.
2. The cold start problem
When a function that hasn't been called for a while is executed, the environment has to be initialized, which delays the response. This tends to be pronounced with languages that start slowly, such as Java and .NET, or when placing functions inside a VPC, and it can affect user experience in APIs that need low latency.
3. Difficulty of debugging and observability
Because the system is split into many small functions, troubleshooting is harder than with a traditional monolithic setup.
- It is hard to fully reproduce in a local environment.
- Tracing processing that spans multiple functions is complex.
- To get the big picture, you need the skill to use dedicated observability tools (CloudWatch Logs, X-Ray, Datadog, etc.).
4. Vendor lock-in
Serverless is tightly integrated with the various services the cloud vendor provides (databases, storage, triggers). As a result, if you later try to move to another cloud or on-premises, migration costs are high, for instance because the whole architecture has to be rewritten.
5. Difficulty of cost prediction
The upside is "zero cost when unused," but it is hard to predict how far costs will balloon when traffic spikes. Also, for workloads under constant heavy load 24/7, it is often more expensive than renting fixed instances.
6. Architectural complexity
Since infrastructure management is no longer needed, that responsibility shifts to application design.
- Retries and idempotency: A retry policy for failures, and a design that is safe even if executed twice.
- Distributed transactions: Ensuring consistency when part of a process spanning multiple functions fails.
All of this has to be solved at the code level, so the team's design skill directly affects productivity.
Criteria for Judging Fit
Cases where serverless fits
- Workloads with unpredictable spikes: When you want automatic scaling for sudden traffic increases.
- Intermittent processing: Batches that run only a few times a day, or endpoints that receive webhooks.
- Event-driven pipelines: Trigger-based processing, such as running a conversion when a file is uploaded.
Cases where serverless doesn't fit
- Long-running processing: Video transcoding or batch analysis of huge datasets.
- Long-lived connections such as WebSocket: Real-time communication that must keep connections open at all times.
- APIs that always require extremely low latency: Systems that cannot tolerate cold starts.
- Constantly high-load systems: If requests keep coming all the time, fixed instances are more cost-efficient.
Summary
Serverless is not a magic wand. It is a choice: "in exchange for entrusting infrastructure management to the cloud vendor, you take on the rigor of application design."
When considering adoption, it is important to judge not only the benefit of reduced operational load but also whether your team can accept the complexity unique to distributed systems.