Event-Driven Architecture: Know your commands from your events


Events and Commands are often used side-by-side in event-driven architectures.

Knowing their differences is important so you can choose the right approach to handling them and choose the right technology stack.

Event vs. Command

An event is a notification that something has already happened. It's a fact, and it’s immutable. e.g. a customer placed an order. Events are not directed at anyone, and we don't care how many (if any) subscribers are listening.

A command is a request to perform a specific action. It’s not just information; it’s an instruction, such as a command to process a payment. Commands are directed at an intended recipient who is responsible for fulfilling the requested action.

We often want to know the result of the action. As such, a command is often followed by an event to report the outcome of the action. e.g. a "process_payment" command is followed by a "payment_succeeded" event upon completion.

Pros & Cons

Events promote loose coupling but make systems less predictable and complex, especially when it comes to handling failures.

Commands simplify your control flow as you know where each command is going, making them easier to debug too. But you increase the coupling between components.

What to use as the bus

Regarding technology choices, EventBridge and SNS are good choices for the event bus, which must broadcast events to multiple subscribers.

SQS is not suitable here because it doesn't do broadcasts.

But SQS is a great fit for the command bus precisely because it’s a targeted delivery where you would have only one subscriber per queue.

Also, messages stay on the queue until they are either expired or processed, which is an important requirement for commands.

Event Sourcing & CQRS

Finally, patterns such as event sourcing & CQRS combine both events and commands to great effect.

Event Sourcing ensures that every change is captured as an event, as you model your system’s state as a series of events rather than snapshots.

CQRS separates read and write operations to optimize performance, where the write operations are modelled as commands.

More on event sourcing and CQRS another time!

Master Serverless

Join 11K readers and level up you AWS game with just 5 mins a week. Every Monday, I share practical tips, tutorials and best practices for building serverless architectures on AWS.

Read more from Master Serverless

Software systems are getting bigger and more complex. And we are constantly looking for ways to test code in production without risking user experience. Canary deployments is a popular mechanism for rolling out changes incrementally, allowing us to limit the blast radius in case something goes wrong. However, they’re not without limitations. Canary deployments essentially sacrifice a small portion of users for the greater good. But what if you want to gain insights without impacting any real...

In security and access control, authentication and authorization are two distinct yet interconnected concepts. Authentication is the process of confirming the identity of a user or system, while authorization defines the actions that the authenticated user is permitted to perform within your system. Although API Gateway integrates directly with Cognito, it lacks built-in support for fine-grained authorization. In a previous article, we looked at implementing fine-grained authorization using a...

A common narrative is that one should always use access tokens to call your APIs, while ID tokens are strictly for identifying users. Some of it has come from this article by Auth0 [1], which makes a strong statement about using ID tokens: However, things are usually more nuanced. In some cases, using ID tokens instead of access tokens is both acceptable and pragmatic. Cognito User Pools might be one of these cases. Cost of using access tokens The common practice amongst Cognito users is to...