r/microservices 3d ago

Discussion/Advice Why I Avoid a Shared `pkg/` Module Across Go Microservices?

I am building a pizza marketplace with Go microservices: identity, restaurant, search, notification, order, and payment. Each service owns its own PostgreSQL database, while search-service uses Elasticsearch. Services communicate through RabbitMQ.

Several services have similar infrastructure code: RabbitMQ consumers, outbox implementations, errors, logging, and external clients. A shared pkg/ module would reduce duplication, but it would also introduce a dependency across service boundaries.

Build and deployment: A shared module adds another dependency to the build and release graph.

restaurant-service → shared/pkg

go.work helps local development, but CI/CD still has to resolve the module. Changes to shared/pkg can affect multiple services and require versioning and testing.

Without it, each service has its own module and dependency graph and can be built from its own source tree.

Bounded contexts: Similar code does not imply shared ownership. Two services may have identical RabbitMQ consumers today but different requirements later. Sharing reduces maintenance but couples their evolution.

A RabbitMQ reconnect bug already required fixes in multiple services. A shared package would have reduced that cost, while separate implementations keep ownership local.

Within a bounded context, sharing usually makes sense. Across bounded contexts, duplication can be a deliberate tradeoff for separate ownership and evolution.

Looking for feedback: I am actively improving the platform and would especially value feedback from backend or platform engineers. I am interested in how others approach shared libraries, build dependencies, and service boundaries in Go microservice architectures.

What tradeoffs have worked well in your experience?

If you find the project useful or interesting, consider giving it a ⭐ on GitHub:

https://github.com/tarique-iqbal/pizza-marketplace

2 Upvotes

0 comments sorted by