Skip to content

Event-driven architecture on AWS

Event-driven architecture integrates services through asynchronous events rather than synchronous calls. A producer emits a fact; a router delivers it; consumers react. Nobody waits for anybody, which is what makes the components scale and fail independently.

An event is a record of something that has already happened, at a specific moment, in a specific system. Three properties follow from that definition and they do most of the work:

  • It is immutable. It records a fact about the past. It cannot be revoked, only superseded by a later event.
  • It is a notification, not a command. It says what changed, when, and with what data. It does not say what anybody should do about it — that is the consumer’s decision.
  • It is broadcast, not addressed. Any number of interested consumers can react: updating their own state, starting a workflow, or maintaining a projection. The producer does not know who they are, which is precisely the coupling that has been removed.

The last point is the one that changes designs. When a producer names its consumers, adding a consumer is a change to the producer. When it emits an event, it is not.

ServiceRole
AWS LambdaServerless compute; runs the logic that reacts to an event
Amazon EventBridgeEvent bus; routes events to targets by content-based rules, across accounts and from SaaS providers
AWS Step FunctionsOrchestrates multi-step workflows, holding state, branching and retries
Amazon SQSQueues and buffers events, absorbing bursts and decoupling producer rate from consumer rate
Amazon SNSPub/sub fan-out to subscribers, including queues, functions, HTTP endpoints and people
Amazon API GatewayFront door for events originating outside the system
Amazon DynamoDBServerless data store; its streams turn writes into events
Amazon S3Object storage that emits events on bucket actions

Choosing between EventBridge, SNS and SQS is a common sticking point. In outline: SQS is point-to-point buffering with at-least-once delivery and dead-letter support; SNS is fan-out with attribute- and content-based filtering and very high subscription counts; EventBridge is routing with content-based rules, schema validation, archive and replay, and the widest set of native AWS targets and third-party sources. Overlaps are substantial — for the quotas and trade-offs that usually settle it, see the integration pattern comparison matrix.

These are the two ways to make several services accomplish one thing, and most real systems use both.

Orchestration — AWS Step Functions. A central workflow holds the state and calls each step in turn. Use it when the process has decision points, needs retries with defined semantics, must be idempotent, or has to be visible as a whole while it runs. The trade-off is that the workflow knows about all the steps, so the coupling that has been removed between services reappears inside the state machine — which is usually the right place for it.

Choreography — Amazon EventBridge. No central coordinator. Each service reacts to events and emits its own; the process is an emergent property of the rules. Use it when producers and consumers should evolve independently, when the set of consumers is expected to grow, and when no single component needs to know the whole flow. The trade-off is that no single component knows the whole flow, which is exactly why tracing and correlation IDs stop being optional.

A common and effective combination: choreograph between bounded contexts, orchestrate within one.

An order-processing system built this way:

  1. Submission. The front end calls API Gateway, which invokes a Lambda function. The function validates the request and publishes an order.created event to EventBridge.
  2. Routing. EventBridge rules match the event and deliver it to the targets that care — here, a Step Functions state machine that decides whether the customer is new.
  3. Fulfilment. The state machine runs the order workflow: update customer data, write to DynamoDB, process the order, and emit an order.processed event when it finishes.
  4. Notification. A rule on that event invokes a function that pushes the update to the waiting client over a WebSocket connection.

Nothing in step 1 knows about step 4. Adding a fraud check, an analytics consumer or an email notification means adding a rule and a consumer, not modifying the order service.

  • Define the event schema deliberately and version it. An event contract is a public interface, and it is harder to change than an API because you cannot see who is reading it. The EventBridge schema registry and CloudEvents are both reasonable starting points.
  • Design for at-least-once delivery. Every consumer must be idempotent. This is not negotiable and it is not something you can add later.
  • Give every event a correlation ID at the edge and propagate it. Without one, a choreographed system is not debuggable.
  • Configure dead-letter queues and retry policies on every target from the outset. The default failure mode of an asynchronous system is silence.
  • Watch the payload sizes. EventBridge caps an event entry at 256 KB. Larger payloads belong in S3 with a pointer in the event.