Serverless Architecture Patterns for Event-Driven Applications
Learn proven serverless architecture patterns for building event-driven applications using AWS Lambda, API Gateway, Step Functions, and EventBridge.
Serverless Architecture Patterns for Event-Driven Applications
Serverless computing fundamentally changes how you design applications. Instead of provisioning servers and managing capacity, you compose managed services that scale automatically and bill per use. But "just deploy Lambda functions" is not an architecture. Without deliberate design patterns, serverless applications become tangled webs of functions that are difficult to debug, test, and maintain.
This guide covers the architectural patterns that make serverless applications reliable, observable, and maintainable in production. These patterns are demonstrated with AWS services but apply conceptually to any serverless platform.
The Event-Driven Foundation
Serverless architectures are inherently event-driven. Every function invocation is triggered by an event: an HTTP request through API Gateway, a message on an SQS queue, an object uploaded to S3, a record inserted into DynamoDB, or a scheduled CloudWatch Event.
Designing around events means thinking about your system as a series of reactions rather than a sequence of procedure calls. An order placement is not a function that calls five other functions in sequence. It is an event that multiple independent functions react to: one validates payment, another reserves inventory, a third sends a confirmation email.
Event design principles:
- Events are immutable facts. An "order placed" event represents something that happened. It cannot be changed, only supplemented by subsequent events like "order cancelled."
- Events carry sufficient context. Include enough data in the event for consumers to act without calling back to the source. An "order placed" event should contain the order items, customer ID, and shipping address - not just an order ID that requires a database lookup.
- Events have schemas. Define and enforce event schemas using tools like EventBridge Schema Registry or JSON Schema validation in your Lambda functions. Schema drift causes silent failures that are notoriously difficult to diagnose.
Pattern 1: API Composition with Lambda and API Gateway
The most common serverless pattern is an HTTP API backed by Lambda functions. API Gateway handles routing, authentication, throttling, and request validation. Lambda functions contain the business logic.
Structuring the API layer:
Use a single Lambda function per route or a small group of related routes, not one monolithic function for the entire API. This keeps functions focused, reduces cold start times (smaller deployment packages), and allows independent scaling.
POST /orders -> createOrder function
GET /orders/:id -> getOrder function
GET /orders -> listOrders function
PUT /orders/:id -> updateOrder function
Direct service integrations bypass Lambda entirely for simple CRUD operations. API Gateway can proxy directly to DynamoDB, SQS, S3, and Step Functions using VTL mapping templates or the newer HTTP API integrations. If a route simply writes to a database, eliminating the Lambda function reduces latency, cost, and code to maintain.
Authorization patterns: Use API Gateway authorizers - either Cognito authorizers for user authentication or Lambda authorizers for custom token validation. This centralizes authentication logic outside your business functions.
Pattern 2: Choreography with EventBridge
Amazon EventBridge is the backbone of loosely coupled serverless architectures. Services publish events to an event bus, and rules route those events to interested consumers. No service knows about its consumers, creating maximum decoupling.
A practical example - e-commerce order flow:
- Order Service publishes "OrderPlaced" to EventBridge
- Rule 1 routes to Payment Lambda, which processes payment and publishes "PaymentProcessed"
- Rule 2 routes to Inventory Lambda, which reserves stock and publishes "InventoryReserved"
- Rule 3 routes to Notification Lambda, which sends order confirmation email
- Rule 4 routes to Analytics Lambda, which records the order for reporting
Each service operates independently. Adding a new reaction to an order (fraud detection, loyalty points) requires adding a new rule and function without modifying existing services.
EventBridge advantages over SNS for choreography:
- Content-based filtering lets you route events based on any field in the event payload, not just message attributes.
- Schema discovery and registry provide documentation and type safety.
- Archive and replay enable recovering from failures by replaying events from a specific time period.
- Cross-account and cross-region event routing supports distributed architectures.
When choreography breaks down: As the number of event types and consumers grows, understanding the complete flow of a business process becomes difficult. If you cannot draw the full order lifecycle on a whiteboard by reading the EventBridge rules, you have outgrown choreography for that workflow.
Pattern 3: Orchestration with Step Functions
When a business process has a defined sequence, conditional logic, error handling, and human approval steps, orchestration with AWS Step Functions is more appropriate than choreography.
Step Functions define workflows as state machines where each state invokes a Lambda function, makes a choice, waits for a callback, or runs parallel branches. The workflow definition is explicit and visual - you can see the entire process flow in the Step Functions console.
Key use cases for Step Functions:
- Order processing with compensating transactions. If payment succeeds but inventory reservation fails, Step Functions orchestrates the refund automatically through defined error handling states.
- Data processing pipelines. Ingest a file, validate its format, transform records, load into a database, and send a completion notification. Each step has retry logic and error handling.
- Human-in-the-loop workflows. Step Functions can pause execution and wait for an external callback - ideal for approval workflows where a human reviews and approves before the process continues.
- Long-running processes. Step Functions can run for up to one year, far exceeding Lambda's 15-minute timeout. Complex batch processing, ML training pipelines, and multi-day approval workflows fit naturally.
Express vs Standard Workflows: Standard Workflows are durable (state tracked per step, exactly-once execution) and suit long-running or critical processes. Express Workflows are high-throughput (at-least-once execution) and suited for event processing that must handle thousands of executions per second at lower cost.
Pattern 4: Fan-Out and Fan-In for Parallel Processing
Many serverless workloads involve processing large datasets in parallel. The fan-out/fan-in pattern distributes work across many concurrent function invocations and aggregates results.
S3 event-driven fan-out:
- A large CSV file is uploaded to S3
- A splitter Lambda divides the file into chunks and writes each chunk to a processing S3 bucket
- Each chunk upload triggers a processor Lambda that transforms the records
- Processed records are written to DynamoDB or another target
- A Step Functions workflow monitors completion and triggers a finalization Lambda
SQS-based fan-out provides better flow control:
- A producer Lambda reads the source data and sends messages to an SQS queue (one message per work item)
- Lambda's SQS integration automatically invokes processor functions with configurable batch sizes and concurrency limits
- Failed messages move to a dead-letter queue for investigation and reprocessing
The SQS approach is preferable because it provides backpressure (the queue absorbs bursts), retries (failed messages are retried automatically), and visibility (queue depth metrics indicate processing health).
Pattern 5: Strangler Fig for Serverless Migration
Migrating an existing application to serverless does not require a big-bang rewrite. The strangler fig pattern incrementally replaces components of a legacy system with serverless implementations.
Implementation approach:
- Place API Gateway in front of your existing application as a reverse proxy. All traffic flows through API Gateway to the existing backend.
- Identify a single, well-bounded piece of functionality to migrate first - a reporting endpoint, a webhook handler, or a notification system.
- Implement the replacement as a Lambda function behind the same API Gateway.
- Route traffic for that specific endpoint to the Lambda function while everything else continues to the legacy backend.
- Repeat for additional endpoints, gradually shifting traffic from the legacy system to serverless.
This approach eliminates migration risk because you can roll back individual routes instantly. It also lets you prove serverless viability with low-risk endpoints before tackling core business logic.
Observability in Serverless Architectures
Serverless applications are distributed by nature, and traditional monitoring approaches fall short. You cannot SSH into a server to check logs or run diagnostic commands.
Essential observability practices:
- Structured logging. Log in JSON format with correlation IDs that flow across function invocations. Every log entry should include the request ID, correlation ID, function name, and relevant business identifiers.
- Distributed tracing with X-Ray. Enable AWS X-Ray tracing on API Gateway, Lambda, and downstream services. Traces show the complete request path across functions, queues, and databases, making it possible to diagnose latency and errors in distributed flows.
- Custom CloudWatch metrics. Publish business metrics (orders processed, payments failed, queue depths) using CloudWatch Embedded Metrics Format. This is cheaper and more efficient than CloudWatch PutMetricData API calls.
- Alerting on error rates, not just errors. A single Lambda error is noise. A 5% error rate increase over 15 minutes is a signal. Configure CloudWatch Alarms on error rates and latency percentiles (p95, p99), not just absolute counts.