Constrange

The database is part of your architecture, not an implementation detail

Why data ownership, transaction boundaries, replication, consistency and schema evolution determine what the rest of the system can do.

Architecture diagrams show services, queues, and APIs. The database appears as a cylinder — sometimes labelled, often generic. Teams debate service boundaries for weeks and treat schema as something migrations handle later. Later arrives: a column added for every exception, a report that scans tables application code was never meant to touch, replication lag that makes the UI lie, and a migration that blocks release because nobody planned evolution as architecture.

The database is not storage beneath the real design. It is where ownership, consistency, and history live. Transaction boundaries, indexing strategy, replication topology, and schema evolution determine what the rest of the system can promise — often more firmly than any microservice boundary drawn above it.

Constrange reads programmes that optimised for deployables and discovered the constraint was relational all along. Treating the database as an implementation detail does not make it disappear. It makes surprises expensive.

Data ownership is architectural ownership

Who owns a service is debated in steering forums. Who owns a table is often unclear until two teams write it. Ownership means who may change shape, who resolves conflicts, who answers audit about truth at a point in time. Without that, services become views on contested ground.

Service layer floating above a database schema with transaction boundaries and replication paths shown as load-bearing structure
Services come and go. The schema remembers.
Service ownership vs data ownership
Service-only thinkingData-aware architecture
API is the contractSchema and API are joint contract
Migrations are DBA workMigrations are design decisions
Reports query ' somehow'Read models are designed paths
Split by team chartSplit by aggregate boundaries
Performance fixed in codePerformance fixed in access patterns

Transaction boundaries define business promises

What must be true together — debited and credited, reserved and confirmed, recorded and notified — belongs in one transaction boundary unless the business explicitly accepts partial states. Splitting services without splitting transactions pushes complexity into sagas, outbox patterns, and reconciliation jobs. Those are valid. They are also architecture, not plumbing.

When architects skip this conversation, engineers inherit impossible promises: the UI says complete while replication lag says otherwise. Finance closes books on numbers operations cannot explain.

  • Money moved in app A; inventory in app B; no shared transaction
  • Dual writes without outbox — silent divergence
  • Long-running locks during peak because schema ignored access path
  • Soft deletes that reports treat as hard truth
  • Foreign keys removed for 'flexibility'; integrity moved to bugs

Replication and consistency are user-visible

Primary-replica topologies, read replicas, and multi-region setups are architecture choices with product consequences. Read-your-writes may fail. Stale dashboards may approve the wrong action. Failover may lose seconds of data someone promised was safe.

These are not operations trivia. They are what the application may truthfully show. Document RPO and RTO where product and finance can read them. Design UI for lag where lag exists. Do not pretend strong consistency because the ORM feels synchronous.

  1. Users refresh until write appears — replication lag unnamed
  2. Analytics on replica breaking operational queries
  3. Failover drill never run; RPO is theoretical
  4. Cross-region conflict resolution undefined
  5. Cache invalidation tied to hope, not events

Schema evolution is the long game

Migrations as programme risk

Services deploy weekly. Schemas persist for years. A column added without migration discipline becomes permanent debt. Backfills block tables. Zero-downtime deploys fail because the schema cannot transition in steps the application supports. The programme slows — not because code is hard, because the data model was not architected for change.

Schema evolution failure modes
PatternCost
Big-bang ALTER in productionOutage or lock storm
Nullable everythingAmbiguous business truth
JSON blob for ' flexibility'Unqueryable reporting pain
No versioned views for readersDeploy coupling
Backfill untested at production volumeWeekend heroics

Access patterns are design, not tuning later

Indexes, partition keys, and denormalisation encode how the business asks questions. Wrong patterns fail at scale regardless of service count. Architects who ignore access paths leave performance to incident response. Query plans become the hidden architecture diagram.

Model read and write paths in design reviews the same way API endpoints are modelled. If reports need a shape the OLTP schema cannot serve, design a read model — deliberately, not via ad hoc joins at month-end.

“You can refactor a service in a sprint. Refactoring a schema the business built on takes quarters. That is why the database is architecture.”Constrange

The ORM is not a boundary

Object-relational mapping speeds delivery and hides SQL until it cannot. Leaky abstractions produce N-plus-one queries, table locks in loops, and migrations generated without human judgement. The database still enforces physics. Ignorance appears as latency and outages, not as clean domain objects.

  • Lazy loading in API hot paths
  • Migration auto-generated without rollback plan
  • Shared database connection pool exhausted by one feature
  • Enum in code; free text in column
  • Historical rows edited instead of appended

Designing with the database on the diagram

Practices that treat data as first-class

Name aggregate roots and transaction boundaries before service lines. Version schema changes with application deploys using expand-contract patterns. Separate OLTP from analytical read paths where load differs. Assign a data owner alongside service owners. Run failover and backfill drills at production scale assumptions.

Include RPO, RTO, and consistency guarantees in architecture decision records — not only in infrastructure tickets. Product should know what 'saved' means.

When splitting services, split data first on paper

  1. Identify aggregates that must stay consistent together.
  2. Define events for what may be eventual.
  3. Plan schema per service before repos multiply.
  4. Prototype reconciliation for cross-aggregate workflows.
  5. Measure migration cost — often the true cost of microservices.

If the paper exercise reveals shared mutable state everywhere, the constraint is data — not deployment. Address that honestly or inherit a distributed monolith with worse integrity.

Reporting and OLTP sharing one schema

The earliest compromise is often analytical queries against operational tables. It works until month-end, when a long-running report locks rows the checkout path needs. The fix is not ' bigger database' alone — it is separating read models, batch windows, or replicas with explicit lag budgets.

When reports define how executives measure the business, the report query becomes architecture whether engineers admit it or not. Design that path deliberately or inherit silent contention as product flakiness.

OLTP vs reporting paths
Shared schema shortcutDesigned read path
Fast to first dashboardPredictable under month-end load
Hidden lock contentionIsolated failure domains
Ambiguous source of truthNamed authoritative store
Schema shaped for screens and slidesModels shaped for each job
Ops tunes indexes in crisisOps rehearses load scenarios

Questions for your next design review

  • Which tables are authoritative for which business facts?
  • What must be atomic — and is it atomic in the database?
  • What does the user see during replication lag?
  • How do we migrate schema without outage at our deploy cadence?
  • Where do reports read — and does that path starve OLTP?

Skipping these questions does not keep architecture pure. It keeps architecture ignorant until production teaches an expensive lesson.

The database is part of your architecture whether or not it appears on the slide. Data ownership, transactions, replication, consistency, and schema evolution set the ceiling on what services can promise. Design there first — or spend the programme unwinding assumptions the cylinder hid.

Services will be rewritten. Languages will change. The data model persists — and judges every shortcut the deployables above it once called temporary.

Programmes that treat schema as detail discover, late, that the cylinder was load-bearing all along. Put it on the diagram with the same rigour as services — ownership, evolution, consistency, and failure — or accept that the hidden architecture will choose your incidents for you.

When the database becomes the programme

Large migrations often discover that the hardest work is not lifting services — it is reconciling decades of implicit schema decisions: nullable columns that encoded business exceptions, status fields that mean different things in different regions, foreign keys that nobody dared remove because a report still depends on them. That work is architecture. It cannot be delegated to a flyway script and wished away over a long weekend.

Teams that win treat schema evolution as a product: versioned, communicated, rehearsed, and owned. Teams that struggle treat it as plumbing — until plumbing blocks the quarter.

Frequently asked questions

Should architects write SQL?

They should understand transaction boundaries, access patterns, and migration risk — not necessarily tune every index.

Is eventual consistency always bad?

No — but it must be named, bounded, and reflected in product behaviour.

When should we split databases per service?

When aggregates and consistency rules are clear — not when microservices slides require it.

How do we fix a shared database microservices mess?

Start with ownership and read paths; split schema incrementally with expand-contract, not big-bang.

Share

LinkedInXWhatsAppFacebookRedditBlueskyEmail
Keep reading

Related posts