The name is misleading: servers exist with serverless too, you just don't see them or manage them. The provider takes care of machines, operating systems, updates and scaling; you supply only the code and pay for the time it actually runs. It is a powerful model for some cases and an awkward one for others, and knowing how it works helps you understand which side your project is on.
The function model
The best-known form of serverless is Function as a Service. You write a function, upload it to the platform and connect it to an event that triggers it:
- an HTTP request to a given address;
- a file uploaded to a storage bucket;
- a message arriving in a queue;
- a schedule, such as every night at two;
- a change in a database.
When the event occurs, the platform starts an execution environment, calls the function and, after a period of inactivity, shuts it down. If a hundred events arrive together, it starts several environments in parallel without you having to do anything.
The concept of serverless is broader than functions, though. It includes databases that scale by themselves and bill per request, managed message queues, services that run containers without exposing servers. The common thread is not having to size or manage machines.
The advantages
You pay only for actual use
A function that receives no requests costs nothing or almost nothing. For services with low or irregular traffic, such as a contact form, an image conversion or a nightly automation, spending can be far lower than for an always-on server.
Automatic scaling
There is no need to predict peaks: the platform increases parallel executions as load grows and reduces them as it falls.
No server maintenance
Operating system updates, machine security fixes and replacement of failed hardware are the provider's responsibility. The code and its dependencies remain yours.
The limits
The cold start
When a function hasn't been used for a while, its environment is shut down. The next request must wait for a new one to be created: this is the cold start. The delay ranges from a few tens of milliseconds to a few seconds, depending on the language, the package size and the platform. For background processing it doesn't matter; for an API that must always respond quickly it can be a problem. Many platforms let you keep some instances always ready, but at a cost.
Execution limits
Functions have limits on maximum duration, memory and request size. A job that takes half an hour must be split into smaller steps or handed to another type of service.
Statelessness
Each execution may take place in a different environment, and nothing left in memory or on disk is guaranteed to be there next time. Sessions, files and data must be stored in external services: databases, caches, object storage.
Database connections
A hundred functions started in parallel can open a hundred connections to the database, exceeding the limits of a traditional database. You need an intermediate connection pooler or databases designed for this kind of access.
Vendor dependency
A function's code is often simple to move, but everything around it, meaning events, permissions, configurations and connected services, is platform-specific. Migrating a complex serverless architecture from one provider to another takes considerable work.
Harder diagnosis
An application split into dozens of event-triggered functions is harder to follow than a single program. Centralized logs, traces and correlation identifiers become indispensable.
When costs flip
Pay-per-use pricing is convenient when usage is low or irregular. With high, constant traffic the situation can reverse: a service receiving requests nonstop, day and night, can cost more as functions than on a properly sized server. It pays to do the math with your own numbers, also counting ancillary items such as API gateways, data transfer and logs.
Suitable and less suitable use cases
| Suitable | Less suitable |
|---|---|
| Processing uploaded files, such as thumbnails or conversions | Applications with persistent connections, such as real-time chat |
| Webhooks and integrations between services | Long, continuous processing |
| Scheduled automations | APIs with very strict latency requirements |
| APIs with low or highly variable traffic | High loads that stay constant over time |
| Prototypes and early-stage projects | Systems that must remain portable across providers |
In my work serverless is at its best as "glue": small functions that react to events and connect different services, alongside a main application running in a more traditional way.
In short
- Serverless means not managing servers: the provider handles machines and scaling, you handle the code.
- Functions are triggered by events and paid for only for execution time.
- The main limits are cold starts, maximum duration, statelessness and database connections.
- With high, constant traffic a traditional server can cost less.
- It is ideal for automations, file processing, webhooks and services with irregular use.