Microservices are often introduced to create autonomous teams. But if every service still shares one database and directly reads other services’ tables, that autonomy disappears quickly.
A team wants to change its data model and first has to discover who else queries the table. One service release depends on another service’s SQL. A schema mistake becomes everybody’s problem.
Database per Service creates a harder boundary: each service owns its data, and other services consume it through a contract rather than by reaching into internal tables.
What problem are we solving?
A shared database creates hidden coupling. Services can look independent on an architecture diagram while remaining tightly connected through the schema.
If the order service owns its data and the payment service owns its own, internal changes in one domain are less likely to break the other. Interaction happens through APIs, events, or other agreed interfaces.
Ownership becomes technical as well as organizational.
What does the business get?
The main business benefit is less coordination around change.
When teams genuinely own their data, they can release changes more independently instead of turning every database migration into a cross-department project.
This matters in larger product organizations where speed is lost not in coding but in the number of dependencies between teams.
There is a risk benefit too: one team’s mistake is less likely to directly damage another domain’s data.
But autonomy is not free. The more data is separated, the more work appears whenever the company needs a complete view across several domains.
What does the team get?
A team can change its own data model without constantly worrying about breaking somebody else’s SQL query.
It can design storage for its workload, plan migrations on its own schedule, and control the performance characteristics of its service more directly.
Responsibility becomes clearer: if the service owns the data, it is accountable for its quality and exposes an agreed way for others to consume it.
What does the customer get?
Customers rarely see how databases are separated. They see the indirect effect: teams can change parts of the product faster and block each other less often.
They may also see the cost: some information may update with a delay when services exchange data asynchronously.
Architecture autonomy therefore has to respect real customer expectations about data freshness.
What do we pay for it?
The largest price is losing the simplicity of one shared transaction and one SQL query across everything.
If orders, payments, and delivery live separately, you cannot simply JOIN all tables. You need APIs, events, read models, data products, or another way to combine information.
Eventual consistency appears: different parts of the system may temporarily see different states of the same business process.
Analytics, backup, recovery, migration, and incident investigation across multiple services also become harder.
When is a separate database per service unnecessary?
If one small team effectively owns all services, releases them together, and does not need independent evolution, strict data isolation may be unnecessary.
A shared database with clearly defined schema ownership can sometimes provide enough structure without full distribution.
Questions to ask before choosing it
- Are shared-schema changes actually slowing us down?
- Do teams need to release independently?
- Which business processes need data from several domains at once?
- Is temporary inconsistency acceptable?
- Are we ready to build separate mechanisms for analytics and cross-domain queries?
In the end
Database per Service does not mean “every microservice must run its own PostgreSQL.” The important part is ownership: other services should not depend on internal tables they do not own.
The business buys team autonomy and pays for it with more complex data movement across boundaries. If autonomy is not needed, the price can exceed the value.