
Event-Driven Architecture: The Hard Parts
Quick takeaways Event-driven architecture (EDA) is powerful but tricky – it’s great for scaling and decoupling, but has many hidden traps. Observability is essential – debugging async systems without tracing, logs, and correlation IDs is almost impossible. Use the outbox pattern – it’s the safest way to publish events without losing data. Design events carefully – large, generic events can lead to tight coupling and painful refactors.

Synchronous vs Asynchronous Architecture
Quick takeaways Start with synchronous architecture by default - it’s simpler to understand, debug, and maintain for most use cases Async architecture improves scalability and resilience - message queues and events help handle traffic spikes and failures Design matters more than the technology choice - tight coupling creates the same problems in both sync and async approaches Consider team experience - async architecture require more experienced teams and better tooling to handle new challenges Adjust as your system grows - external APIs, heavy operations, or the need to handle failures gracefully are good use cases Hybrid approach - use both sync and async where they fit best, rather than forcing one over the other Introduction In this episode, we discuss when to choose synchronous versus asynchronous architecture for backend systems.

Watermill: from a hobby project to 8k stars on GitHub
Quick takeaways Solve real problems first - successful open source projects start by addressing actual needs, not by looking for problems to fit a solution Keep breaking changes minimal - Watermill stayed on v1 for 6 years with no breaking changes in the core library, building trust with users Examples and documentation are crucial - provide real-world examples with automated tests, not just simple “hello world” demos Promotion matters - creating a great library isn’t enough; you need to actively share it through conferences, blog posts, and communities Be patient with growth - Watermill took 7 years to reach 8,000 stars; overnight success in open source is rare Introduction In this episode, we share the story of how Watermill, our event-driven library for Go, grew from a side project to a popular open source library with over 8,000 GitHub stars and 100+ contributors.

Watermill 1.4 Released (Event-Driven Go Library)
It’s Autumn over here, and it usually means another release of Watermill! 🍂 It’s hard to believe it’s already been five years since the v1.0 release. In case you’re new to Watermill, here’s TL;DR. Watermill is a Go library for building message-driven or event-driven applications the easy way. Think of it like an HTTP router but for messages. It’s a library, not a framework, so you don’t need to change your architecture to use it.

Distributed Transactions in Go: Read Before You Try
In the previous post, I looked into running transactions in a layered architecture. Now, let’s consider transactions that need to span more than one service. If you work with microservices, a time may come when you need a transaction running across them. Especially if the way they are split was an afterthought (the unfortunate but likely scenario). Service A calls service B, which calls service C, and if something goes wrong at the end, the system becomes inconsistent.

Watermill 1.3 released, an open-source event-driven Go library
Hey, it’s been a long time! We’re happy to share that Watermill v1.3 is now out! What is Watermill Watermill is an open-source library for building message-driven or event-driven applications the easy way in Go. Our definition of “easy” is as easy as building an HTTP server in Go. With all that, it’s a library, not a framework. So your application is not tied to Watermill forever.
Series
Popular articles
- The Go libraries that never failed us: 22 libraries you need to know
- Safer Enums in Go
- Common Anti-Patterns in Go Web Applications
- How to implement Clean Architecture in Go (Golang)
- The Repository pattern in Go: a painless way to simplify your service logic
- Introduction to DDD Lite: When microservices in Go are not enough
Tags
- go
- golang
- watermill
- ddd
- clean-architecture
- domain-driven design
- events
- web-applications
- anti-patterns
- event-driven
- software-development
- ci
- firestore
- architecture
- cloudrun
- gcloud
- googlecloud
- serverless
- testing
- advanced
- databases
- devops
- firebase
- gitlab
- microservices
- reactive
- repository
- backend
- basics
- building-business-applications
- building-in-public
- cqrs
- frameworks
- kafka
- mysql
- nats
- pipelines
- scalability
- software-architecture
- transactions
- amqp
- authentication
- balance
- bounded-context
- c4
- cicd
- code-quality
- code-review
- design-patterns
- diagrams
- docker
- dry
- e-book
- efficiency
- enums
- event-storming
- gamedev
- generics
- google-cloud
- grpc
- htmx
- intermediate
- iteration
- javascript
- learning
- libraries
- maintainability
- metrics
- monolith
- open-source
- openapi
- over-engineering
- overengineering
- parallelism
- productivity
- programming-languages
- prometheus
- pull-requests
- python
- rabbitmq
- retrospective
- security
- sql
- sse
- startups
- strategic-ddd
- swagger
- terraform
- tips
- unpopular-opinions
- versioning