Introduce databases, object storage, authentication, secrets, messaging, notifications, and workflow services as core parts of the serverless toolbox. Explain why serverless usually means "many managed services working together."
Managed services are what make most serverless systems real. If functions are the execution units, managed services are where identity, storage, messaging, notifications, secrets, and workflow state usually live. That is why serverless architecture is almost never “just functions.” It is a composition model in which several provider-managed capabilities replace infrastructure that teams used to build or operate directly.
This composition is powerful because it reduces undifferentiated platform work. It is also where coupling becomes easy to hide. A function calling a queue, a database, an object store, an auth service, and a notification service may look simple because each individual integration is managed. But the overall architecture still needs ownership, data flow discipline, and clear failure handling.
flowchart TD
A["API or event trigger"] --> B["Function"]
B --> C["Object storage"]
B --> D["Database or key-value store"]
B --> E["Queue or topic"]
B --> F["Secrets and config service"]
B --> G["Auth or identity service"]
E --> H["Workflow or downstream function"]
What to notice:
Most serverless platforms are built from a recurring set of managed building blocks:
These services are not optional decorations. They are the platform substrate that short-lived compute depends on.
Traditional applications often centralize several concerns inside one long-running host process. A serverless system usually pushes those concerns outward:
This makes the architecture more modular, but it also means more boundaries must be understood explicitly.
The following simplified example shows how a “small” serverless workflow is really a composition of several services.
1entry_point:
2 type: http
3 route: POST /uploads
4
5compute:
6 function: accept-upload
7
8managed_services:
9 - object_store
10 - metadata_store
11 - queue
12 - auth_service
13 - secrets_service
1export async function acceptUpload(request: RequestContext) {
2 const user = await auth.verify(request.token);
3 const storageKey = `uploads/${request.body.uploadId}`;
4
5 await objectStore.write(storageKey, request.body.file);
6 await metadataStore.put({
7 uploadId: request.body.uploadId,
8 ownerId: user.id,
9 status: "queued",
10 });
11
12 await queue.publish({
13 uploadId: request.body.uploadId,
14 storageKey,
15 });
16
17 return { accepted: true };
18}
This is a useful example because the function itself is short. Most of the real system behavior is carried by managed services:
Managed building blocks are powerful because they let teams reuse mature capabilities instead of rebuilding them:
This is one of the strongest reasons serverless can help small and medium teams move quickly.
The common failure mode is that teams treat each managed service choice as locally convenient without seeing the whole dependency graph. Over time, the system becomes difficult to reason about because:
Managed does not mean simple. It means the complexity moved to service boundaries.
A few practical rules help:
These are not rigid laws, but they keep service boundaries clearer.
A team says its serverless system is simple because each function is under fifty lines long. In reality, every request path touches an auth layer, an API gateway, a queue, a document store, an object store, and a notification service. Is the system actually simple?
Not necessarily. The stronger answer is that code length is not the right measure. The system may still be well-designed, but the real architecture lives in the interaction between managed services. A short function can sit inside a complex and fragile service graph if ownership, failure handling, and observability are weak.