Architecture pattern library

AWS field guide

Decouple consumers with event-driven fan-out

Publish a durable business fact once and let independent consumers evolve without sharing a synchronous failure domain.

Use this pattern when

A business event must trigger several workflows without coupling their availability or deployment schedules.

Reference architecture

Responsibilities and controls, not a deployment template.

Synchronous Asynchronous

Producer

Publishes a business fact

Amazon EventBridge

Durable event bus

Routing rules

Match by event contract

Amazon SQS

Queue per consumer

AWS Lambda

Independent consumers

AWS service marks use the official Q3 2026 AWS Architecture Icons. Abstract nodes represent application responsibilities rather than AWS services.

Decisions that shape the pattern

  • Name events after completed business facts.
  • Version schemas for compatibility.
  • Give critical consumers their own queue.

Security boundaries

  • Restrict who can publish each event family.
  • Remove sensitive payload fields.
  • Use resource policies for cross-account buses.

Reliability posture

  • Assume at-least-once delivery.
  • Make consumers idempotent.
  • Configure dead-letter queues and replay procedures.

Starter implementation

Start from deployable infrastructure

Review every permission, limit, Region, and cost assumption before production.

Download ADR template
event-driven-fanout.stack.ts
import { Duration, Stack, StackProps } from 'aws-cdk-lib';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as athena from 'aws-cdk-lib/aws-athena';
import * as bedrock from 'aws-cdk-lib/aws-bedrock';
import * as budgets from 'aws-cdk-lib/aws-budgets';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
import * as cloudtrail from 'aws-cdk-lib/aws-cloudtrail';
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as patterns from 'aws-cdk-lib/aws-ecs-patterns';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';
import * as glue from 'aws-cdk-lib/aws-glue';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as kms from 'aws-cdk-lib/aws-kms';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as sources from 'aws-cdk-lib/aws-lambda-event-sources';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
import * as sqs from 'aws-cdk-lib/aws-sqs';
import { Construct } from 'constructs';

export class PatternStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const bus = new events.EventBus(this, 'DomainBus');
    const queue = new sqs.Queue(this, 'ConsumerQueue', {
      deadLetterQueue: { queue: new sqs.Queue(this, 'DeadLetterQueue'), maxReceiveCount: 5 },
    });
    const rule = new events.Rule(this, 'OrderCreated', {
      eventBus: bus,
      eventPattern: { source: ['orders'], detailType: ['OrderCreated'] },
    });
    rule.addTarget(new targets.SqsQueue(queue));
  }
}

Before production

Adoption checklist

  1. 01Assign an event owner.
  2. 02Document the schema and version.
  3. 03Add an idempotency key.
  4. 04Set retry and dead-letter policies.
  5. 05Test replay with production-like volume.

From the journal

Selected from service names and architecture signals used by this pattern.

Was this playbook useful?

One click helps prioritize deeper examples and updates.