When Serverless Fits
Serverless computing offloads infrastructure management to the cloud provider. You write functions or managed services, and AWS handles provisioning, scaling, patching, and high availability.
Serverless excels in these scenarios:
Event-driven workloads: S3 object uploads triggering image processing, DynamoDB streams driving analytics, or SQS messages triggering order processing. The function runs only when an event arrives—you pay nothing at rest.
Variable or unpredictable traffic: An e-commerce API that handles 100 requests per minute normally but 10,000 during a flash sale. Lambda scales automatically from zero to thousands of concurrent executions without pre-provisioning.
Rapid prototyping: Deploy a REST API with API Gateway + Lambda in minutes. No EC2 instances to manage, no load balancers to configure. Focus on business logic, not infrastructure.
Microservice decomposition: Each Lambda function handles one responsibility—one function processes payments, another sends emails, another generates reports. Independent scaling, deployment, and failure isolation.
Serverless may not fit: long-running processes (Lambda has a 15-minute timeout), workloads requiring consistent high throughput (provisioned concurrency costs negate savings), or applications needing specific OS-level configurations. For these, containers on ECS/EKS or EC2 are better choices.
Cost model: You pay per request and per millisecond of compute. A function handling 1 million requests at 200ms each costs roughly $0.40. Compare this to running an EC2 instance 24/7 at $50+/month—even if that instance sits idle 90% of the time.
Fan-Out/Fan-In Pattern
Fan-out/fan-in distributes work to multiple parallel workers and aggregates results. It's the map-reduce of serverless.
Fan-out: A Lambda function publishes messages to an SNS topic or invokes multiple Lambda functions in parallel. Each worker processes a subset of the work independently.
Fan-in: As workers complete, they write results to DynamoDB, S3, or an SQS queue. A coordinator function or Step Functions state machine collects all results and performs the final aggregation.
Real-world example—a video transcoding service:
- User uploads a video to S3
- A Lambda function (fan-out) splits the video into 10 segments
- 10 parallel Lambda functions each transcode one segment
- A Step Functions state machine waits for all 10 to complete (fan-in)
- A final Lambda function merges segments and notifies the user
Implementation with Step Functions:
{
"Type": "Map",
"ItemsPath": "$.segments",
"MaxConcurrency": 10,
"Iterator": {
"StartAt": "Transcode",
"States": {
"Transcode": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:transcode-segment"
}
}
}
}
The Map state iterates over a list and runs the same workflow for each item, with configurable concurrency.
Saga Pattern for Distributed Transactions
The Saga pattern manages distributed transactions across multiple services without two-phase commit. Each step has a compensating action that undoes it if a later step fails.
Choreography saga: Each service listens for events and decides what to do next. An order service publishes OrderCreated, the inventory service reserves stock and publishes StockReserved, the payment service charges and publishes PaymentProcessed. If payment fails, it publishes PaymentFailed, triggering the inventory service to release the stock.
Orchestration saga: A central orchestrator (Step Functions) controls the sequence. It calls each service in order and handles compensations if any step fails:
{
"StartAt": "ReserveInventory",
"States": {
"ReserveInventory": {
"Type": "Task",
"Resource": "arn:aws:states:::ecs:runTask",
"Next": "ProcessPayment",
"Catch": [{
"ErrorEquals": ["States.ALL"],
"Next": "ReleaseInventory"
}]
},
"ProcessPayment": {
"Type": "Task",
"Resource": "arn:aws:lambda:...:process-payment",
"Next": "ShipOrder",
"Catch": [{
"ErrorEquals": ["States.ALL"],
"Next": "RefundPayment"
}]
}
}
}
Use choreography for simple, loosely coupled services. Use orchestration when the workflow is complex, has many steps, or requires centralized visibility.
Strangler Fig and CQRS Patterns
The Strangler Fig pattern incrementally replaces a monolith with microservices without a big-bang migration. Route traffic to the new service for specific paths while the rest goes to the monolith.
Implementation with API Gateway:
# Route /api/v2/orders to new Lambda service
paths:
/api/v2/orders:
x-amazon-apigateway-integration:
uri: arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/new-order-service/invocations
/api/v2/orders/{id}:
x-amazon-apigateway-integration:
uri: arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/new-order-service/invocations
# Everything else routes to monolith
/{proxy+}:
x-amazon-apigateway-integration:
uri: http://monolith-internal-alb.amazonaws.com/{proxy}
Over time, migrate more routes until the monolith is empty and can be decommissioned.
CQRS (Command Query Responsibility Segregation) separates read and write models. Commands (create, update, delete) go to a write database (DynamoDB). Queries (read, search) go to a read-optimized store (ElastiCache, OpenSearch). An event bridge (EventBridge or DynamoDB Streams) keeps the read model in sync.
Benefits: read and write scales independently, read models can be denormalized for query performance, and write models enforce business rules without read concerns. The trade-off is eventual consistency—read models may lag behind writes by milliseconds to seconds.
Quiz
1. When is serverless computing most cost-effective?
2. What is the fan-out/fan-in pattern?
3. What is the key difference between choreography and orchestration sagas?
Flashcards
Question
What is the strangler fig pattern?
Click to reveal answer
Answer
Incrementally replacing a monolith by routing traffic to new microservices for specific paths while the rest goes to the monolith, avoiding big-bang migrations.
Question
What is CQRS?
Click to reveal answer
Answer
Command Query Responsibility Segregation—separating read and write models so they can be scaled, optimized, and designed independently.
Question
What is a cold start in serverless?
Click to reveal answer
Answer
The latency added when a serverless function is invoked for the first time or after idle time, as the platform provisions resources and initializes the runtime.
Question
What is the saga pattern?
Click to reveal answer
Answer
A pattern for managing distributed transactions where each step has a compensating action to undo it if a later step fails, avoiding the need for two-phase commit.
Revision Notes
Key Takeaways
- 1. Serverless excels for event-driven, variable, and rapid-prototyping workloads
- 2. Fan-out/fan-in parallelizes work and aggregates results—use Step Functions for orchestration
- 3. Saga pattern replaces distributed transactions with compensating actions
- 4. Strangler fig enables incremental monolith migration via traffic routing
- 5. CQRS separates read and write models for independent scaling and optimization
Interview Tips
- • Give an example of when you'd choose serverless over containers and why
- • Explain how you'd implement fan-out/fan-in for a data processing pipeline
- • Describe the trade-offs between choreography and orchestration sagas
- • Explain how CQRS handles eventual consistency between read and write models
Cheat Sheet
Serverless fits: event-driven, variable traffic, rapid prototyping. Patterns: fan-out/fan-in (parallel work + aggregation), saga (compensating transactions), CQRS (separate read/write), strangler fig (incremental migration). Trade-offs: cold starts, 15-min timeout, eventual consistency in CQRS.