EventBridge and Step Functions
EventBridge routes events between services by rules (choreography); Step Functions runs explicit state machines with retries and compensation (orchestration). Execute an order workflow that succeeds, retries and compensates.
🎯 What you'll learn
- EventBridge buses, rules, targets, schemas, archive/replay
- Step Functions states: Task, Choice, Parallel, Map, Wait
- Retries, catches and saga compensation
- Combining choreography and orchestration
📚 Before you start
Two serverless building blocks for event-driven (choreography) and workflow (orchestration) designs (distributed-systems/message-brokers/11-event_driven_architecture, distributed-systems/fundamentals/08-distributed_transactions).
1EventBridge: an Event Bus With Routing Rules
{
"source": "petpal.orders",
"detail-type": "OrderPlaced",
"detail": { "orderId": "o-17", "customerId": "c-4", "total": 4599, "currency": "EUR" }
}- Event buses: the
defaultbus (AWS service events like "EC2 instance state change"), custom buses for your application events, partner buses (SaaS: Stripe, Zendesk, Datadog…). - Rules match events with event patterns and send them to up to 5 targets (Lambda, SQS, SNS, Step Functions, API destinations — any HTTPS endpoint, Kinesis, another bus, ECS tasks…):
{
"source": ["petpal.orders"],
"detail-type": ["OrderPlaced"],
"detail": { "total": [{ "numeric": [">", 10000] }], "currency": ["EUR"] }
}- Input transformers reshape the event for each target; DLQs and retry policies per target (retries up to 24 h).
- Archive & replay: keep events and replay them into the bus (rebuild a read model, recover from a consumer bug).
- Schema registry and discovery generate code bindings for event types.
- EventBridge Pipes: point-to-point source (SQS, Kinesis, DynamoDB Streams, Kafka) → filter → enrich (Lambda/Step Functions/API) → target, without glue Lambdas.
- EventBridge Scheduler: one-time or recurring schedules (cron/rate, time zones) invoking any target — replaces "cron Lambda" patterns.
EventBridge vs SNS vs SQS: EventBridge = content-based routing with rich filtering, many targets, SaaS integration, archive/replay, ~$1 per million events, a bit more latency; SNS = high-throughput fan-out pub/sub with simpler filtering; SQS = durable queue for one consumer group (07-sqs_and_sns/). Common combination: EventBridge rule → SQS queue per consumer (buffering + retries).
2Step Functions: Workflows as State Machines
A state machine (defined in Amazon States Language, JSON/YAML, or visually in Workflow Studio) orchestrates steps with built-in retries, error handling, timeouts and state:
{
"StartAt": "ReserveStock",
"States": {
"ReserveStock": {
"Type": "Task", "Resource": "arn:aws:states:::lambda:invoke",
"Parameters": { "FunctionName": "reserve-stock", "Payload.$": "$" },
"Retry": [{ "ErrorEquals": ["States.TaskFailed"], "MaxAttempts": 3, "BackoffRate": 2, "JitterStrategy": "FULL" }],
"Catch": [{ "ErrorEquals": ["OutOfStock"], "Next": "NotifyOutOfStock" }],
"Next": "ChargeCard"
},
"ChargeCard": {
"Type": "Task", "Resource": "arn:aws:states:::lambda:invoke",
"Parameters": { "FunctionName": "charge-card", "Payload.$": "$" },
"Catch": [{ "ErrorEquals": ["States.ALL"], "Next": "ReleaseStock" }],
"Next": "ShipOrder"
},
"ReleaseStock": { "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "Parameters": { "FunctionName": "release-stock", "Payload.$": "$" }, "Next": "OrderFailed" },
"ShipOrder": { "Type": "Task", "Resource": "arn:aws:states:::sqs:sendMessage", "Parameters": { "QueueUrl": "https://sqs…/shipping", "MessageBody.$": "$" }, "End": true },
"NotifyOutOfStock": { "Type": "Pass", "End": true },
"OrderFailed": { "Type": "Fail", "Error": "PaymentFailed" }
}
}State types: Task (do work), Choice (branch), Parallel, Map (iterate — Distributed Map processes millions of S3 items with high concurrency), Wait (seconds or until a timestamp — free waiting, unlike Lambda), Pass, Succeed, Fail.
Integrations: 200+ AWS services called directly (arn:aws:states:::dynamodb:putItem, ecs:runTask.sync, glue:startJobRun.sync) — no Lambda glue. Patterns: request/response, .sync (wait for job completion), .waitForTaskToken (pause until an external system or human calls SendTaskSuccess with the token — approvals, callbacks).
| Standard workflows | Express workflows | |
|---|---|---|
| duration | up to 1 year | up to 5 minutes |
| semantics | exactly-once step execution, full history | at-least-once (async) / at-most-once (sync) |
| pricing | per state transition (~$25 per million) | per request + duration (cheap at high volume) |
| use | business processes, sagas, human approval | high-volume event processing, IoT, streaming transforms |
3Choreography + Orchestration Together
A common shape: services publish domain events to EventBridge (loose coupling between bounded contexts); inside a context, a Step Functions workflow orchestrates a multi-step transaction with compensations (a saga), emitting events at the end. Events for "tell others"; workflows for "do these steps reliably in order".
Under the HoodHow Step Functions Remembers Where It Is▾
Each Standard workflow execution is a durable log of history events (TaskStateEntered, TaskScheduled, TaskSucceeded, ExecutionSucceeded…) persisted by the service. The orchestrator processes the state machine as a series of transitions: on each event it evaluates the current state's definition, applies InputPath/Parameters/ResultSelector/ResultPath/OutputPath to shape the JSON passed along (max 256 KB — store large payloads in S3), schedules the next task, and records it. Because state lives in the service, not in your code, a workflow can wait a week for a callback, survive deployments, and retry a failed step with backoff without keeping any compute running. Retries are scheduled by the service using the Retry rules (IntervalSeconds, BackoffRate, MaxDelaySeconds, JitterStrategy), and Catch routes errors — including timeouts and task-token heartbeats — to compensation states.
⚠️ Common Pitfalls
- Lambdas that call other Lambdas synchronously in chains — use Step Functions.
- Waiting inside Lambda (sleep/poll) instead of
Waitstates or task tokens. - Large payloads through state (256 KB limit) — pass S3 pointers.
- No DLQ on EventBridge targets — failed deliveries vanish after retries.
- Overly broad event patterns — every consumer receives everything, coupling returns.
- Express workflows for steps that must not run twice (at-least-once).
📋 Quick Reference
EventBridge: bus → rule (event pattern) → ≤5 targets · input transformer · DLQ + retries · archive/replay · Pipes · Scheduler
Step Functions: ASL states (Task/Choice/Parallel/Map/Wait) · Retry + Catch · direct service integrations · .sync · .waitForTaskToken
Standard (≤1 year, exactly-once, per transition) vs Express (≤5 min, high volume, cheap)
events between contexts, workflows within a context (sagas)🧠 Key takeaways
- EventBridge: publish events to a bus; rules filter by content and route to targets (with retries, DLQs, archive/replay).
- Step Functions: explicit workflows with Retry/Catch, Choice, Parallel, Map, Wait and full execution history.
- Model sagas with Catch → compensation; use Standard (long, exactly-once) vs Express (high-volume, short).
- Combine: EventBridge between services, Step Functions within a service's workflow.
🎤 Interview Q&A
Q1What is EventBridge?core▾
A serverless event bus: services and SaaS apps publish events; rules match event patterns and route them to targets (Lambda, SQS, Step Functions, APIs). It also offers schedules, pipes (source → filter → enrich → target), archive and replay.
- EventBridge vs SNS? EventBridge has richer content filtering, schemas and SaaS integrations; SNS has higher throughput and lower latency fan-out.
Q2What are Step Functions and when do you use them?core▾
Managed state machines that orchestrate steps (Lambda, ECS, AWS SDK calls) with retries, error handling, parallel branches, waits and human approvals. Use for multi-step workflows and sagas where you want visibility and reliability.
- Standard vs Express workflows? Standard: long-running (up to a year), exactly-once, per-transition pricing. Express: high-volume, short (5 min), at-least-once, cheaper.
Q3How do you implement a saga with Step Functions?senior▾
Each step calls a service; Catch blocks route failures to compensating steps (refund, release inventory) in reverse order, with retries configured per step.
- Why orchestrate rather than choreograph here? Clear visibility of state and simpler failure handling.
Q4How do you schedule jobs on AWS today?core▾
EventBridge Scheduler (one-time and recurring schedules with time zones, retries and DLQs) targeting Lambda, ECS tasks, Step Functions or many AWS APIs.
- Old approach? CloudWatch Events cron rules.
Q5How do you handle event schema evolution in EventBridge?core▾
Use the schema registry and discovery, version event detail-types, keep changes backward compatible, and test rules against sample events.
- Replay use case? Reprocessing archived events after fixing a consumer bug.
🛠️ Practice exercises
Each exercise is a file in this topic folder. Code exercises are self-checking: run them and make the checks pass.
✅ Check yourself
Answer the questions — feedback is instant.