βοΈ Serverless Computing Principles
"Serverless" doesn't mean there are no servers β it means you stop thinking about them. In this lesson you'll build a clear mental model of the serverless execution model, learn the two big categories (FaaS and BaaS), and understand the trade-offs that decide when serverless is the right tool for the job.
π― Learning Objectives
By the end of this lesson, you will be able to:
- Define serverless computing and explain why the servers are still there even though you don't manage them
- Distinguish Function as a Service (FaaS) from Backend as a Service (BaaS)
- Describe the five core principles: no server management, pay-per-execution, auto-scaling, event-driven execution, and statelessness
- Weigh the key trade-offs β cold starts, duration limits, state complexity, and vendor lock-in
- Recognise the workloads where serverless shines and the ones where it doesn't
Estimated Time: 30β40 minutes β’ Difficulty: Intermediate
Hands-on: Sketch a serverless architecture for a real feature and defend your choices.
In This Lesson
What Is Serverless, Really?
Serverless computing is a cloud execution model where the provider dynamically allocates, runs, and tears down the compute your code needs β on demand, per request. Your code runs in short-lived, stateless containers that are created when an event arrives and disposed of soon after. You never provision a machine, patch an OS, or configure a load balancer; you upload code and describe what should trigger it.
π The name is misleading
There are absolutely still servers. "Serverless" describes your experience, not the hardware: server management disappears from your responsibilities and lands entirely on the provider. A better name might have been "server-invisible."
π‘ Analogy β owning a car vs. calling a rideshare. A traditional server is a car you lease: you pay for it around the clock, you handle insurance and maintenance, and you must guess how big a vehicle to buy before you know the demand. Serverless is a rideshare: you pay only for the trips you actually take, someone else maintains the fleet, and a bigger vehicle β or ten more of them β shows up automatically when you need capacity. When you're not travelling, you pay nothing.
That single shift β from "capacity you rent" to "work you consume" β is what drives every other property of serverless. Keep it in mind as we go.
Two Flavours: FaaS and BaaS
"Serverless" is an umbrella over two related but distinct ideas.
FaaS] A --> C[Backend as a Service
BaaS] B --> B1[AWS Lambda] B --> B2[Azure Functions] B --> B3[Google Cloud Functions] B --> B4[Cloudflare Workers] C --> C1[Auth & identity] C --> C2[Managed databases] C --> C3[Object storage] C --> C4[Managed APIs]
Function as a Service (FaaS)
You write small, single-purpose functions and hand them to the platform. The platform runs a function when its trigger fires β an HTTP request, a file upload, a queue message, a schedule β and scales the number of concurrent copies to match the load. This is the part people usually mean when they say "serverless."
// A minimal AWS Lambda handler (Node.js)
export const handler = async (event) => {
const name = event.queryStringParameters?.name ?? 'World';
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
message: `Hello, ${name}!`,
timestamp: new Date().toISOString(),
}),
};
};
Backend as a Service (BaaS)
Instead of writing the backend feature yourself, you consume a fully-managed one through an SDK or API: authentication, a realtime database, file storage, push notifications. Firebase, Supabase, Auth0, and AWS Cognito are classic examples. You still write frontend and glue code, but whole categories of backend work simply vanish.
| Aspect | FaaS | BaaS |
|---|---|---|
| What you provide | Your own function code | Configuration & API calls |
| What runs it | Provider's function runtime | Provider's managed service |
| Typical examples | Lambda, Azure Functions, Cloud Functions | Firebase Auth, Supabase, Cognito, S3 |
| Best for | Custom business logic | Common, undifferentiated features |
Real applications freely mix the two: a Lambda function (FaaS) that verifies a token issued by Cognito (BaaS) and writes to DynamoDB (BaaS).
The Five Core Principles
1 Β· No server management
You are abstracted entirely away from provisioning, patching, and scaling machines. This is the top of a long evolution β each step handed more responsibility to the provider:
2 Β· Pay-per-execution
Billing is metered on actual invocations, execution time, and memory β not on reserved capacity. When nothing is happening, you pay nothing (this is called scaling to zero). For spiky or low-volume workloads the savings are dramatic:
| Hosting model | Typical monthly cost* | Note |
|---|---|---|
| Dedicated server | $40β$100 | Constant, whether busy or idle |
| Container (autoscaled) | $20β$60 | Needs tuning; rarely scales to zero |
| Serverless | $0β$20 | Scales to zero; cost tracks real usage |
*Rough illustrative figures for an API serving ~1M requests/month; your mileage will vary by provider and workload.
3 Β· Automatic scaling
The platform runs as many concurrent copies of your function as demand requires, from zero to thousands, with no configuration. A traffic spike simply causes more instances to spin up; the surge subsides and they disappear. There is no capacity to plan and no idle fleet to pay for during the quiet hours.
4 Β· Event-driven execution
Functions don't run in a loop waiting for work β they are triggered by events. This is the beating heart of the model.
function] E2[File uploaded] --> F E3[Queue message] --> F E4[DB change] --> F E5[Schedule / cron] --> F F --> R1[(Database)] F --> R2[Object storage] F --> R3[External API]
5 Β· Statelessness
Each invocation may land on a brand-new container with no memory of previous runs. Any state you need must live in an external service. We'll dig into what that means for your code next.
Statelessness in Practice
Because the execution environment is ephemeral, you cannot rely on in-memory variables or the local filesystem to survive between requests. Instead, push state into a database, cache, or object store. Here is the pattern β notice that the client is created once outside the handler (so a re-used "warm" container can share it) while the actual state lives in Redis:
import { createClient } from 'redis';
// Created once per container and reused across warm invocations.
// This is NOT durable state β it is a connection we happen to keep alive.
const redis = createClient({ url: process.env.REDIS_URL });
let connected = false;
export const handler = async (event) => {
if (!connected) {
await redis.connect();
connected = true;
}
const sessionId = event.headers['x-session-id'];
const key = `session:${sessionId}`;
// Durable state lives in Redis, not in the function
const raw = await redis.get(key);
const session = raw ? JSON.parse(raw) : { visits: 0 };
session.visits += 1;
session.lastVisit = new Date().toISOString();
await redis.set(key, JSON.stringify(session), { EX: 3600 });
return {
statusCode: 200,
body: JSON.stringify({ visits: session.visits }),
};
};
β οΈ The subtle trap
Global variables might persist between invocations that reuse the same warm container β but there is no guarantee. Use that persistence only as an optimisation (like reusing a database connection), never as your source of truth. If your correctness depends on a value surviving, store it externally.
Trade-offs & Limitations
Serverless is powerful, not magic. Know the sharp edges before you commit.
Cold starts
When no warm container is available, the platform must create one β load the runtime, import dependencies, run initialisation β before your handler executes. That first-request latency is the cold start.
π‘ Mitigating cold starts
- Keep deployment packages small β fewer dependencies load faster
- Prefer fast-starting runtimes (Node.js, Python, Go) over slow ones (JVM cold starts are heavy)
- Use provisioned concurrency to keep instances pre-warmed for latency-critical paths
- Initialise heavy clients outside the handler so warm containers skip the work
Execution-duration limits
FaaS platforms cap how long a single invocation may run, so they are unsuitable for long batch jobs. Split long work into steps or move it to a container/queue-worker instead.
| Platform | Max execution time |
|---|---|
| AWS Lambda | 15 minutes |
| Azure Functions (Consumption) | 10 minutes |
| Google Cloud Functions (2nd gen) | up to 60 minutes (HTTP) |
| Cloudflare Workers | CPU-time limited (seconds of active CPU) |
State & testing complexity
Statelessness forces every bit of shared state into external services, and locally reproducing cloud triggers (an S3 upload event, a DynamoDB stream) is fiddly. Tools like the AWS SAM CLI, the Serverless Framework's offline plugin, and LocalStack help, but local behaviour never perfectly mirrors the cloud.
Vendor lock-in
Deep use of provider-specific services (DynamoDB, Cognito, EventBridge) makes switching clouds costly. Reduce the blast radius by keeping core business logic free of provider SDKs (hexagonal architecture) and hiding cloud services behind your own interfaces.
β οΈ Serverless is a poor fit whenβ¦
β¦you have steady, high, predictable traffic 24/7 (a reserved server may be cheaper), you need very long-running processes, you require ultra-low and consistent latency without provisioned concurrency, or you need deep control over the OS and networking stack.
When to Reach for Serverless
Serverless excels at event-driven, bursty, and glue-code workloads:
| Use case | Why serverless fits |
|---|---|
| REST / GraphQL API backends | Scales per request; pay only for calls served |
| File & media processing | An upload event triggers resize/transcode work on demand |
| Webhooks & integrations | Sporadic third-party events, no idle server needed |
| Scheduled / cron jobs | Runs on a timer without an always-on host |
| Real-time notifications | Fan-out email / push / SMS from a single event |
β The Black Friday test
A shop normally handles 100 requests/second but peaks at 5,000 during a sale. Traditionally you'd over-provision 50Γ capacity weeks ahead and pay for it all month. Serverless simply scales up within seconds when the surge hits and back down afterwards β you pay for the peak only while it's happening.
Hands-on Exercise
ποΈ Design a Serverless "New Photo" Pipeline
Objective: Practise thinking in events and managed services instead of servers.
Scenario: Users upload profile photos. For each upload you must (1) generate a 200Γ200 thumbnail, (2) strip GPS metadata for privacy, and (3) record the photo in a database so it appears in the user's gallery.
Your task
- Identify the trigger that starts the pipeline.
- Decide which pieces are FaaS (your functions) and which are BaaS (managed services).
- List the state stores involved and what each holds.
- Note one trade-off you'd watch for (e.g., a cold start on a large image, or the duration limit on a huge upload).
π‘ Hint
Object storage can emit an event the moment a file lands. That single event can fan out to more than one function. Databases and storage buckets are managed (BaaS); the resize and metadata-stripping logic is your custom code (FaaS).
β Example solution
Trigger: an "object created" event from the storage bucket (BaaS) fires when the upload completes.
- FaaS:
generateThumbnailandstripMetadatafunctions, each subscribed to the upload event; arecordPhotofunction writes the gallery entry. - BaaS: object storage (originals + thumbnails buckets) and a managed database for gallery rows.
- State: the images live in storage; the metadata/gallery record lives in the database. Nothing is kept in the functions.
- Trade-off: a very large image could approach the memory limit or add cold-start latency β cap upload size and give the resize function enough memory (which also raises its CPU).
Quiz
π― Check Your Understanding
Question 1: What does "scaling to zero" mean for a serverless function?
Question 2: Which statement about FaaS vs. BaaS is accurate?
Question 3: Why should you store session data in an external service rather than a global variable inside a function?
Summary & Next Steps
π Key Takeaways
- Serverless means the provider manages the servers β not that servers are gone.
- FaaS runs your functions; BaaS gives you managed backend features. Real apps mix both.
- The model rests on five principles: no server management, pay-per-execution, auto-scaling, event-driven execution, and statelessness.
- Keep durable state in external stores; treat warm-container globals only as an optimisation.
- Mind the trade-offs β cold starts, duration limits, state complexity, and vendor lock-in β and pick serverless for event-driven, bursty workloads.
π Further Reading
π What's Next?
Now that you understand the model, we'll go hands-on with the most widely used FaaS platform. In AWS Lambda Function Development you'll write, configure, secure, and deploy real functions.