EventBridge best practice: why you should wrap events in event envelopes


When it comes to building event-driven architectures on AWS, EventBridge has become the de facto service for ingesting, filtering, transforming and distributing events to their desired destinations.

It provides a standard envelope encapsulating each event, including metadata like the source, detail type, and timestamp.

These fields are useful, but I'm gonna give you several reasons why you should wrap your event payload in its own envelope. For example, like this:

1. Clear separation between metadata and business data

Adding a custom envelope lets you organize the structure of your events to create better separation between metadata and your business data.

You should have a standard set of metadata fields across all your events, while the payload contains only business-relevant and event-specific data. That way, when you look at the events, there is less clutter in the way.

2. Interoperability between different services

This consistent structure is especially important if you work with other messaging services, such as SNS and Kinesis as well. Having a consistent and predictable structure makes it easier to understand and parse events, especially when multiple teams or systems are involved.

It also makes it easier to write reusable code that can process events that are delivered through different messaging services.

When EventBridge forwards an event to another event bus (e.g. when you have a multi-account environment), the forwarded event has a different ID. Having adding your own event ID in the envelope, you have a consistent identifier for the event, no matter where the subscriber gets the event from.

3. Better event filters

Having a standardized set of metadata fields in your envelope (like the one I showed above) means you can more easily filter events and receive only the events you want.

Yes, you can include additional fields for filtering in the event data itself. However, doing so on an event-by-event basis lacks consistency, especially across multiple teams.

Imagine you can filter events by "domain" for some teams' events but not others. You'd have to ask the event publishing team to add those same fields so you can use the same filter across multiple teams' events.

4. Versioning

Systems change over time, and so do the structures of your events.

Wrapping events in a custom envelope provides a better way to handle versioning and backward compatibility.

By adding a "version" field in your envelope, you can evolve your event structures without breaking existing consumers. (There's more to this than simply adding a version attribute! But more on this in another post.)

Each consumer can check the event version and process it accordingly.

5. Idempotency

EventBridge gives you a unique ID for each event, but you should have a unique event ID in your envelope.

Because there are many ways the same domain event might be duplicated in EventBridge.

For example, when a previously failed event is reprocessed from a DLQ [1].

Or maybe the sender retries a timed-out request because it didn't receive EventBridge's response in time. The AWS SDK has built-in retries, so this might have happened with you realising.

If EventBridge receives the same domain event twice, it will deliver them as two separate events to the target, each with its own unique event ID.

If you forward events from EventBridge to, say, SQS, then EventBridge's at-least-once delivery semantic can also create duplicates further downstream.

Having your own event ID helps you identify these duplicates and implement idempotency control in your processing logic.

6. Observability

You can add a correlation-id field in the envelope to help you trace through a chain of events. The field is initialized by the first publisher in the chain and reused by subsequent consumers and publishers.

That way, you can trace a user transaction through the follow-up events, too. For example, in a choreography, a microservice receives an event, does its thing and creates a follow-up event. If the initial event includes a correlation-id metadata field, the microservice will include this in its own events.

7. Audit

You should also add "createdBy" or "updatedBy" fields in the envelope as well.

This improves traceability for regulatory or debugging purposes.

What metadata fields should you have?

Here are some metadata fields that I typically include:

  • id: This is the unique ID for the event.
  • version
  • timestamp: When you published the event, not when EventBridge received it.
  • domain: Not to be confused with "service". A domain represents a problem space that your system is supposed to address. Within a domain, you might have many services working together to solve the problem.
  • service
  • type: Event type.

This is a good starting point, but limit yourself to these. As mentioned before, for audit purposes, you might also have fields such as "createdBy" or "updatedBy".

What to put in the event body itself?

Ok, so that's the metadata fields.

What about the event body itself?

Do you put a bunch of entity IDs like I did in the example above?

Or do you expand them into complete entities like this?

Each approach has its merits and is best suited to different situations.

So, in the next post, let's look at when you should use light events vs. rich events.

Links

[1] How to reprocess Lambda dead-letter queue messages on-demand

Master Serverless

Join 17K readers and level up you AWS game with just 5 mins a week.

Read more from Master Serverless

Modern applications rarely do just one thing at a time. An API request creates an order, and then another service needs to reserve stock, another to charge the customer, another to send an email, and so on. In a serverless or event-driven architecture, follow-up actions are usually triggered by messages (either events or commands). That gives us loose coupling, better scalability, and independent services. But it also introduces a reliability problem. “What happens when the database update...

If you use Claude Code a lot, you’ve probably run into usage limits, sometimes even in short coding sessions. But cost isn’t the only problem. In long-running sessions, the context window eventually fills up, and that can cause the agent to forget earlier decisions, lose important details, or come back from compaction with gaps in its working memory. Here are three tools worth checking out if you want to reduce token usage and make longer coding sessions possible. 1. CavemanThis is a Claude...

AI agents can now scan an entire open-source codebase for exploitable vulnerabilities in hours. Frontier models carry the complete library of known bug classes in their weights. So you can simply point an AI agent at a codebase and tell it to find zero-days. This isn't theoretical. Willy Tarreau, the HAProxy lead developer, reports that security bug reports have jumped from 2–3 per week to 5–10 per day. Greg Kroah-Hartman, the Linux kernel maintainer, described what happened: "Months ago, we...