Technical
EventBridge Patterns That Keep Handlers Decoupled
EventBridge looks like another message bus until you use it properly. Its real value is eliminating direct calls between services, which turns monoliths into loosely coupled pieces without the cost of a full microservices migration. Eight months of using it in production has given me three patterns I trust.
Pattern One: Domain Events, Not Commands
An event describes something that happened. A command asks for something to happen. Naming matters: PostPublished is an event. PublishPost is a command. EventBridge handles events well. Commands belong in a queue or a direct call.
Why it matters: events have zero, one, or many listeners. The producer does not know and does not care. That is the decoupling that makes the architecture flexible.
{
"source": "blog.posts",
"detail-type": "PostPublished",
"detail": {
"slug": "article-slug",
"title": "Article Title",
"publishedAt": "2025-11-20T10:00:00Z"
}
}Pattern Two: Consumer Idempotency
EventBridge guarantees at-least-once delivery. Your consumers must handle duplicates. I include a deterministic event_id derived from the domain state, and every consumer checks a processed_events set before acting. Skipping this step is how weird bugs happen in production.
Pattern Three: Schema Discovery, Not Documentation
Events get new fields over time. Writing a wiki page that lists them ages badly. Instead, I let EventBridge's schema registry infer schemas from live traffic. Consumers subscribe to a version and fail loudly if the shape drifts. Self-updating contracts beat stale docs.
The Failure Modes I Plan For
Consumer is down. DLQ catches undelivered events for replay. A one-line setting, huge safety.
Event storm from a bug. A rate limit on the producer keeps a loop from draining my monthly budget. Circuit breaker pattern applies here.
Schema drift. Consumers fail loudly on unknown event shapes instead of silently losing data. Loud failures at deploy time beat silent failures in production.
What This Enables
Adding a new consumer to an existing event is zero-risk. The publish site does not change. The other consumers do not know. Want analytics on PostPublished? Add a consumer. Want to trigger a newsletter on PostPublished? Add another. The system stays additive.
What It Is Not For
Synchronous responses. Real-time user-facing flows where the user waits for a result. Use a direct call for those. Event buses are background and fan-out, not request/response.
EventBridge earns its place when you treat it as an event distributor, not a message queue.
Cost Sanity Check
EventBridge bills per million events. For the blog workload I run, that is pennies per month. For a chatty service emitting per-keystroke telemetry, it would be a bad fit. Know the traffic shape before you choose the bus. Rough rule: if your events are under 100 per second at steady state, EventBridge is cost-effective. Above that, Kinesis or MSK start making sense. I have never crossed the threshold on a client project, so this stays theoretical for me.
RELATED READING
The Consulting Shift I Am Making In Year Two
After a year of writing and building, my consulting practice is changing shape. Shorter engagements. Sharper outcomes.
ReadThe Frontend Shift: Shipping Less JavaScript In Year Two
A year ago I reached for Next.js for everything. This year I often reach for nothing.
ReadThe Serverless Lesson I Would Write On A Sticky Note
After a year of shipping serverless projects, one rule explains most of the wins and all of the losses.
Read