The Architecture Reference

Cld serverless · Cloud & SaaS · Intermediate

Event-Driven Serverless Patterns

Compose serverless systems from named patterns — storage-first, functionless integration, gatekeeper bus, choreography vs. orchestration — over an event-driven backbone.

Cld serverless Intermediate ⏱ 5 min read Complete

🧭 Analogy

A busy restaurant runs on tickets, not shouting. An order is written down (stored) before anyone cooks it; the printer fans tickets to the right stations; line cooks react to their own tickets (choreography) while the expediter coordinates a complex banquet (orchestration). Serverless patterns are these tickets — proven ways to move work without losing it.

Patterns are guides, not silver bullets

Serverless is both influenced by decades of prior patterns (GoF, enterprise integration, microservices) and generative of new ones. The substrate of every pattern is resilience, idempotency, and loose coupling built over an event-driven backbone — where immutable events (something that already happened) flow between decoupled services via producers, consumers, and event carriers (buses/brokers).

The event bus: Amazon EventBridge

EventBridge is the fully managed serverless event bus — it ingests, filters, transforms, and routes events to up to five targets per rule. Key facts that shape design: at-least-once delivery with no ordering guarantee, retries up to 24 hours then a dead letter queue (DLQ), and a 256 KB max event payload. Auxiliary features include archive and replay, a schema registry, EventBridge Scheduler, and EventBridge Pipes (one source → one target with filter/transform/enrich).

graph TD
P["Producer<br/>(publish-and-forget)"] --> SF["Storage-first<br/>(store before process)"]
SF --> EB["EventBridge bus<br/>(filter + route)"]
EB --> C1["Consumer A<br/>(idempotent)"]
EB --> C2["Consumer B<br/>(idempotent)"]
EB -. undeliverable .-> DLQ["Dead letter queue"]
C1 --> R["Event relay<br/>(emit new event,<br/>never modify-and-relay)"]

A catalog of named patterns

  • Storage-first pattern (Eric Johnson) — “store first, process after.” Persist incoming data in SQS, Kinesis, S3, or DynamoDB before computing, so async decoupling never loses data; choice depends on retention. Enables idempotency and audit logs.
  • Strangler fig pattern (Fowler) — incrementally migrate legacy to serverless, strangling it piece by piece (redirect data flows into a common S3 bucket; run old and new API routes in parallel behind an API Gateway or BFF façade).
  • Circuit breaker pattern — fail fast when a dependency is unhealthy to avoid retry storms and runaway cost. States: closed, open, half-open. Lambda has none built-in; implement with a status check in SSM/DynamoDB or a dedicated status service, with store-and-replay while open.
  • Functionless integration pattern — connect services with native integrations and IaC instead of “transport” Lambdas (API Gateway VTL, Step Functions direct + AWS SDK integrations, EventBridge API destinations). Benefits: less code, fewer failure points, fewer IAM policies, lower cost. Keep a function where you need detailed or censored logs.
  • Gatekeeper event bus pattern — a dedicated custom bus guarding a bounded-context boundary, controlling event outflow (only domain events leave) and inflow (only required events enter), isolating encryption, cross-account routing, and DLQs.

Idempotency and ordering

Because delivery is at-least-once with no ordering guarantee, consumers must be idempotent (handle duplicates) and must not rely on order — sort by timestamp or sequence numbers. Never modify-and-relay an event; use the event relay pattern and emit a new event under your own identity.

Choreography vs. orchestration

  • Choreography — no central controller; services react to events independently (the dancers analogy). Considerations: event loss (retries + DLQ), duplicates, action sequencing, distributed resiliency, and traceability via an immutable trace_id plus AWS X-Ray.
  • Orchestration — a central conductor coordinates steps, branches, and collation. AWS Step Functions is the orchestrator; chaining Lambdas via synchronous invocations is an antipattern. Types: in-service, cross-service, and distributed (long-running async via task tokens and the callback pattern).
  • Saga pattern — consistency across distributed transactions as atomic local steps, undone by compensating transactions, with pivot transactions marking the point of no return.
graph LR
subgraph CH["Choreography (no controller)"]
  S1["Service A"] -- event --> S2["Service B"]
  S2 -- event --> S3["Service C"]
end
subgraph OR["Orchestration (central conductor)"]
  SF["Step Functions"] --> A1["Service A"]
  SF --> A2["Service B"]
  SF --> A3["Service C"]
end

Key insight

Use Lambda to transform, not transport. Wherever a function only moves data between services, reach for a native integration instead — fewer moving parts means fewer failures, lower cost, and a smaller security surface.

See also

When to use it — and when not

✅ Reach for it when

  • Connecting decoupled microservices via events, messages, and managed integrations
  • You need resilience: idempotency, dead-letter queues, store-before-process guarantees
  • Deciding between central orchestration and decentralized choreography

⛔ Think twice when

  • A simple single-service workload where patterns add accidental complexity
  • Chaining functions synchronously (an antipattern) instead of using events or workflows
  • Relying on event ordering or exactly-once delivery from at-least-once buses

Check your understanding

Score: 0 / 4

1. What does the storage-first pattern require?

Storing first means async decoupling never loses data, and it enables idempotency via uniqueness checks and audit logs.

2. Why must serverless event consumers be idempotent?

EventBridge delivers at-least-once with no ordering guarantee, so consumers must safely tolerate duplicate events.

3. What is the functionless integration pattern?

Native integrations (API Gateway VTL, Step Functions SDK, EventBridge) reduce code, failure points, IAM policies, concurrency risk, and cost. 'Transform, not transport.'

4. What distinguishes choreography from orchestration?

In choreography services react to events independently (dancers); in orchestration a central conductor coordinates steps, branches, and collation.

Comments

Sign in with GitHub to join the discussion.