Skip to content

The Problem with Shared Databases

A shared database looks like integration without the hard parts. In production it quietly couples ownership, releases, and failure modes. Architecture Files #10.

Architecture Files #10 · Part of Binary and Beyond. LinkedIn newsletter edition follows.

The shared database is the most persuasive shortcut in enterprise architecture.

Two products need the same customer table.

Two teams need the same inventory numbers.

A new service needs "just a few reads" from an existing schema.

Someone draws a box labeled DB with five arrows into it and calls the meeting done.

No APIs to negotiate. No sync jobs to schedule. No eventual consistency debate. One source of truth, sitting right there in Postgres.

Then production happens.

And the shared database turns out to be the most expensive kind of coupling: the kind that looks like simplicity until a release, an index, or an ownership argument breaks three products at once.

The schema that belonged to everyone

Picture a mid-market retailer that grew by adding modules around one commerce database.

Orders lived there.

Customers lived there.

Inventory lived there.

Then support needed ticket history, so support wrote into the same tables.

Finance needed recognition fields, so finance added columns.

A warehouse team needed reservation flags, so warehouse wrote those too.

Marketing needed segments, so marketing ran heavy queries against live order rows during campaign season.

Nobody designed a platform.

They designed a parking lot.

Every team could park. Nobody owned the paint.

On a busy Tuesday, a "harmless" migration to speed up support search locked order writes long enough for checkout to time out. Payments authorised. Orders stalled. Retries multiplied the damage (Production Notes #05).

The database was healthy by every DBA metric that matters for a single app.

The business was not.

That is the problem with shared databases: physical proximity is not the same as a shared contract.

What "shared" actually shares

A database is not only storage.

It is:

  • a schema (names, nullability, meaning)
  • a write path (who may change what, and when)
  • a failure domain (locks, vacuum, connection pools, bad queries)
  • a release boundary (migrations that force every consumer to move together)
  • a political object (who gets paged when the table is hot)

When two products share a database, they share all of that whether they admit it or not.

Production Notes #03 argued that many systems claiming one truth actually hold different authorities. A shared database often invents the opposite failure: one physical truth with too many writers, so authority collapses into whoever shipped the last column.

Production Notes #07 covered the fiction that every noun is a row you can overwrite. Shared databases amplify that fiction: every consumer gets a UPDATE door into someone else's commitments.

Why teams reach for it first

Shared databases win planning meetings for understandable reasons.

They are fast to demo.

They avoid building an integration.

They let reporting join everything with SQL.

They feel like "single source of truth" without the vocabulary tax of APIs and events.

They also match how many organisations already grew: one app, then five features bolted onto the same schema because the first path worked.

The cost arrives later, and it arrives as operational surprise:

1. Release coupling.
A migration for one team becomes a freeze for everyone. "Just add a column" becomes a cross-product change review.

2. Performance coupling.
One team's analytics query is another team's checkout latency. Connection pools do not care whose feature flag caused the spike.

3. Semantic coupling.
status = shipped means three different things to three teams. The column is shared. The meaning is not (Production Notes #01).

4. Failure coupling.
A lock, a bad index, or a runaway job is a brownout for every product touching the table (Production Notes #04).

5. Ownership fog.
When data is wrong, every team points at the schema. Nobody owns the definition of "available" or "paid."

Shared read replicas are not the same problem

There is a useful distinction teams blur.

Shared write database across product boundaries is usually the expensive pattern.

Read models / replicas / warehouses fed by explicit contracts can be healthy, if consumers cannot mutate the source of authority and the lag is named (Production Notes #09).

The danger is not SQL.

The danger is unbounded write sharing without a boundary for ownership, migration, and meaning.

If marketing needs a join across orders and campaigns, give them a read model. Do not give them a write password to the order table.

When a shared database is still the right call

Shared databases are not always wrong.

They can be correct when:

  • One product team owns the schema end to end
  • Writers are few, known, and governed by the same release train
  • The domain is still one application, not three products wearing a common table
  • You can afford to treat a migration as a product-wide event

They become wrong when:

  • Multiple product orgs ship on independent cadences into the same tables
  • "Temporary" write access becomes permanent
  • Reporting and OLTP compete on the same connections
  • You need independent scale, compliance boundaries, or blast-radius isolation

The litmus test is simple:

Can one team change the schema without asking another team's permission, and without risking their release?

If no, you do not have a shared database.

You have a distributed system with a single point of failure and no API.

A design checklist before you "just share the DB"

I use these questions when a diagram draws five arrows into one cylinder:

  • Who owns each table's meaning? Name a team, not "platform."
  • Who may write? If the answer is "several services," list the invariants those writers must never break.
  • What is the migration contract? Who tests, who freezes, who rolls back?
  • What happens when one consumer runs a bad query? Is checkout allowed to share that failure domain?
  • Is this really shared writes, or do you need a read model?
  • If we split later, what joins become integrations? Design that boundary now, even if the split waits.
  • How do we detect semantic drift? Two teams using one column for two meanings is a silent production bug.

If the answers are vague, the shared database is not buying simplicity.

It is deferring an ownership conversation into an incident.

AI and shared tables make the same mistake

Teams wiring AI enrichment into production often grant the agent or the pipeline write access to the "main" tables because it is convenient.

That is shared-database thinking with a new coat of paint.

An enrichment job that updates customer rows under load is another writer with another definition of done. When it retries, it inherits every problem from Production Notes #05 and Production Notes #06.

Give AI a bounded write surface. Or a queue. Or a side table with an explicit merge contract.

Do not let "the model needs context" become a second product living inside your order schema.

How shared databases show up in modernization

Legacy modernization briefs often open with "we need microservices" when the real pain is a shared write schema that five teams treat as a private API.

You do not fix that by standing up containers around the same tables.

You fix it by naming ownership, then carving write paths until each product can change its meaning without taking checkout hostage.

That is slow work. It is also the only work that reduces blast radius.

A strangler pattern that leaves every service writing to orders is not a strangler.

It is a shared database with more deploy pipelines.

When agencies bring QBF into that kind of brief, the useful first deliverable is rarely a framework choice. It is a map: which tables are truly shared writes, which can become read models tomorrow, and which "temporary" joins have already become the product.

A different standard for "integration"

Integration is not only HTTP.

Sometimes integration is a foreign key and a shared password.

That form is quieter. It is not cheaper.

The teams I trust treat a shared write database as a last resort for true single-product ownership, not as the default glue between departments.

They prefer boring boundaries: owned schemas, explicit APIs or events, named lag, and clear writers.

Enterprise software does not usually fail because someone refused to share a table.

It fails because everyone shared one without agreeing what the rows meant, who could change them, or which product was allowed to go down when the table got busy.


Related reading


Architecture Files #10 · Part of Binary and Beyond. LinkedIn newsletter edition follows. Building production-grade delivery with clear data ownership boundaries? Start a conversation.

Agency partner

Need delivery stability without adding headcount?

Quick Brown Fox helps agencies ship complex web platforms, tighten QA, and scale engineering capacity—without becoming a liability to your client relationships.