Background
Sections
IntroductionRequirements & Problem AnalysisConstraints & AssumptionsEstimation TechniquesFunctional vs Non-Functional RequirementsMoSCoW PrioritizationSystem Design FundamentalsArchitecture DiagramClass DiagramComponent DiagramData Flow Diagram (DFD)ER Diagram (Entity-Relationship Diagram)High Level Design (HLD)Low Level Design (LLD)Sequence DiagramState DiagramUse Case DiagramData StorageDocument StoresFile StorageGraph DatabasesIn-Memory DatabasesKey-Value StoresNewSQLNoSQL DatabasesObject StorageSQL Databases (RDBMS)Time-Series DatabasesWide-Column StoresDatabase ConceptsACID PropertiesCAP TheoremConsistency ModelsIndexingNormalization & DenormalizationReplicationSharding & PartitioningTransactions & Isolation LevelsScalabilityAuto-Scaling & ElasticityConsensus & Leader ElectionLoad BalancingReplication & Read ReplicasSharding & PartitioningVertical vs Horizontal ScalingAvailability & ReliabilityBackup & Data DurabilityCircuit BreakerData ConsistencyDisaster RecoveryFault Tolerance & FailoverGraceful DegradationHigh AvailabilityNetworkingCDNDNSFirewalls & VPNHTTP & HTTPSLoad Balancer & Reverse ProxyTCP/IP & UDPWebSocketsCachingCache InvalidationCache Read/Write PatternsCaching LayersEviction PoliciesRedis vs MemcachedMessaging & CommunicationDead-Letter QueueIdempotencyKafka vs RabbitMQ vs SQSMessage QueuesPub/SubCompute & ServicesAPI GatewayContainers & OrchestrationMonolith vs MicroservicesServerlessService DiscoveryService MeshWeb Server & App ServerAPI DesignAPI Versioning & IdempotencyAuthentication & AuthorizationGraphQLgRPCPaginationRate Limiting & ThrottlingRESTSecurityAuthentication & AuthorizationData PrivacyEncryptionInput Validation & InjectionOAuth2 & JWTSecrets ManagementXSS & CSRFStorage & File SystemsBackup & RetentionBlock vs File vs Object StorageData Lakes & WarehousesDistributed File SystemsEphemeral StorageObservability & MonitoringDistributed TracingHealth ChecksLoggingMetricsSLI, SLO, SLADesign PatternsBulkhead PatternCircuit Breaker PatternCreational PatternsRate Limiter PatternRetry PatternStructural & Behavioral Patterns

Serverless

7 min read

In a Nutshell

Serverless means running code without managing servers — you write a function, hand it to a cloud provider, and it runs on demand, scaling automatically from zero to thousands of concurrent executions and back, and you pay only for the actual execution time. The servers still exist, of course; you just don't provision, patch, or scale them. The canonical form is Functions-as-a-Service (FaaS) like AWS Lambda, where each function is triggered by an event (an HTTP request, a file upload, a queue message) and runs briefly. Serverless shines for spiky, event-driven, or unpredictable workloads where you'd otherwise pay for idle capacity — but it comes with real constraints (cold starts, time limits, statelessness) that make it a poor fit for others.

2D minimalistic diagram showing an event (HTTP request, file upload, or queue message) on the left triggering a serverless function that spins up on demand, executes briefly, and disappears; a scaling indicator shows functions multiplying from zero to many instances under load and back to zero, with a "pay per execution" meter

How It Actually Works

The Serverless Model

Traditional server:      always running, you pay 24/7, you manage it,
                         you scale it, idle capacity costs money.

Serverless function:     idle = 0 instances = $0.
                         event arrives → provider spins up an instance →
                         runs your function → tears it down.
                         1000 events at once → 1000 instances → auto-scaled.
                         You pay only for execution time (per ms).

Key Characteristics

Property Meaning
Event-driven Functions run in response to triggers (HTTP, queue, schedule, storage event)
Auto-scaling Provider scales instances up/down automatically, including to zero
Pay-per-use Billed by invocations × duration × memory — no charge when idle
Stateless Each invocation is independent; no guaranteed local state between calls
Managed No servers to provision, patch, or scale
Ephemeral Short-lived (seconds to minutes); execution time is capped

The Cold Start Problem

The defining trade-off of serverless. When a function hasn't run recently, the provider must spin up a fresh execution environment — loading the runtime and your code — before it can handle the request. This adds latency:

Warm start: environment already exists → runs immediately (~ms)
Cold start: provision runtime + load code + init → then run
            (tens of ms to several seconds, depending on runtime/size)

Worst for: latency-sensitive user-facing paths, large deployment packages,
           heavy runtimes (JVM), and sporadic traffic (always cold).
Mitigations: provisioned concurrency (keep instances warm), lighter
           runtimes, smaller packages, keep-warm pings.

When Serverless Fits — and When It Doesn't

Great Fit Poor Fit
Spiky / unpredictable traffic Steady high-volume traffic (cheaper on reserved servers)
Event-driven processing (file uploads, stream events) Long-running jobs (exceed time limits)
Glue code / webhooks / automation Latency-critical paths sensitive to cold starts
Infrequent workloads (pay nothing when idle) Stateful apps needing local persistence
Rapid prototyping Workloads needing fine-grained hardware control

The Constraints You Design Around

  • Time limits — functions are capped (e.g., ~15 min on Lambda); long jobs must be broken up or moved to containers.
  • Statelessness — no reliable local disk/memory between invocations; state lives in external stores (S3, DynamoDB, Redis).
  • Cold starts — as above.
  • Vendor lock-in — functions and their event bindings are provider-specific; portability takes effort.
  • Resource limits — memory, package size, and concurrency caps.
  • Debugging/observability — distributed, ephemeral execution makes local debugging harder; you lean on tracing and logs.

Serverless Beyond FaaS

Serverless is broader than functions — it's a billing and operations model. Managed "serverless" databases (DynamoDB, Aurora Serverless), queues (SQS), and container runtimes (AWS Fargate, Cloud Run) all share the traits: no server management, auto-scaling, pay-per-use. "Serverless containers" (Fargate/Cloud Run) notably relax FaaS constraints — longer runtimes, more control — while keeping the no-ops, scale-to-managed benefits.

2D minimalistic timeline diagram comparing cold start vs warm start: two horizontal bars, the top "cold start" bar showing segments for "provision environment", "load code/runtime", "init", then "execute" (long total); the bottom "warm start" bar showing only a short "execute" segment because the environment already exists, illustrating the added latency of cold starts

Seeing It in Action

Scenario: Image-processing pipeline — a textbook serverless fit.

Requirement: users upload photos; generate thumbnails + extract metadata.
Traffic is SPIKY and unpredictable (bursts when users are active, zero at night).

Serverless design:
  S3 bucket "uploads"  ──(object-created event)──▶  Lambda: process-image
                                                       ├─ generate thumbnails
                                                       ├─ extract EXIF metadata
                                                       ├─ write thumbs → S3
                                                       └─ write metadata → DynamoDB

Why serverless is ideal here:
  ✅ Event-driven: each upload naturally triggers one function
  ✅ Spiky load: 0 uploads at 3am = $0; 5000 uploads at noon = auto-scale
     to 5000 concurrent executions, no capacity planning
  ✅ Short tasks: thumbnailing takes seconds — well under time limits
  ✅ Stateless: each image processed independently; state in S3/DynamoDB
  ✅ No idle cost: with servers you'd pay 24/7 for peak capacity you
     rarely use; serverless bills only for actual processing time

Where you'd NOT use serverless in the same app:
  ✗ The main API with steady, high, latency-sensitive traffic → cheaper and
    cold-start-free on containers/servers behind a load balancer.
  ✗ A 2-hour nightly batch aggregation → exceeds function time limits →
    use a container/batch job instead.

The decision heuristic: serverless wins when workloads are event-driven, spiky, short, and stateless — you trade a bit of cold-start latency and vendor lock-in for zero idle cost and zero ops. It loses for steady, long-running, latency-critical, or stateful workloads, where reserved servers or containers are cheaper and more predictable. Real systems mix both: serverless for the bursty event-processing edges, containers/servers for the steady core.

Interview Questions

  1. Q: What is serverless, and what are its defining characteristics? Hint: Running code without managing servers — the provider provisions, scales (including to zero), and patches infrastructure; you pay only for execution time. Characteristics: event-driven (triggered by HTTP/queue/storage/schedule), auto-scaling, pay-per-use (no idle cost), stateless, ephemeral (short-lived, time-capped), and fully managed. FaaS (Lambda) is the canonical form.

  2. Q: What is a cold start and how do you mitigate it? Hint: When a function hasn't run recently, the provider must spin up a fresh execution environment (load runtime + code + init) before handling the request, adding latency (ms to seconds). Worst for latency-sensitive paths, heavy runtimes (JVM), large packages, and sporadic traffic. Mitigate with provisioned/warm concurrency, lighter runtimes, smaller packages, and keep-warm invocations.

  3. Q: What workloads are a good fit for serverless, and which are not? Hint: Good: spiky/unpredictable traffic, event-driven processing (uploads, stream events), glue/webhook/automation code, infrequent workloads (zero idle cost), prototyping. Poor: steady high-volume traffic (cheaper on reserved servers), long-running jobs (exceed time limits), latency-critical paths (cold starts), and stateful apps needing local persistence.

  4. Q: What constraints must you design around with FaaS? Hint: Execution time limits (break up or move long jobs to containers), statelessness (keep state in S3/DynamoDB/Redis, not local disk), cold-start latency, vendor lock-in (provider-specific bindings), resource limits (memory, package size, concurrency), and harder debugging/observability of ephemeral distributed executions (rely on tracing/logs).

  5. Q: Is serverless only about functions? What about serverless containers? Hint: No — serverless is a billing/operations model (no server management, auto-scaling, pay-per-use) that also covers managed databases (DynamoDB, Aurora Serverless), queues, and container runtimes. Serverless containers (AWS Fargate, Cloud Run) relax FaaS constraints — longer runtimes, more control, fewer cold-start issues — while keeping the no-ops, auto-scaling, pay-per-use benefits. They bridge FaaS and traditional containers.

References

Dive Deeper