Event-driven Architecture Best Practices

Michael Moreno
6 min readDec 16, 2023

In the pursuit of ever more scalable software, I recently introduced the concept of an event-driven architecture (EDA) to my team. Together, over just a couple sprints, we were able to transform service classes with sprawling methods, having ill-defined responsibilities, into something more modular and loosely coupled. In the course of the work, I saw my teammates making some missteps that would have lead to defects, performance bottlenecks, and design problems down the line. I don’t fault them for this. The switch to an event-driven architecture was a big mental leap from how the system previously worked, and there were no established patterns in the codebase to follow. Now that the work is done, I thought it would be a good idea to publish an article detailing the approaches I ended up suggesting to them, in the hope that other developers will read this and not make the same mistakes. I’ll keep this article at a high level, discussing concepts, not lines of code.


First, I’d like to give a quick rundown of the specific flavor of EDA that I introduced to my team, and the one I’ll be discussing below.

It works like this: services, either before or after having performed some action, can emit events signifying that something is about to occur, or that something has just occurred. Listeners (sometimes called consumers or subscribers), listen for events they’re interested in, and then pass along the event data to other services that perform business logic on that event data.