Skip to content

CONCEPT Cited by 1 source

Practice #4: Everybody gets their own database instance

Definition

Practice #4 is the fourth of the seven practices of evolutionary database design (Fowler 2003, Sadalage 2006). Stated cleanly:

"Every developer has their own instance of the database that they can play with as they like. Other developers can't see what they are doing and they can ignore changes made to other people's instances. The full database state is captured by the schema and the test data."

(Fowler, Evolutionary Database Design, 2003)

The practice is methodologically central: it makes experimentation cheap, removes coordination cost, eliminates the "what's broken on staging right now" problem, and enables the other six practices (especially Practice #5 "all changes are database refactorings" — refactorings need a sandbox to be tested in before they're committed).

Why it stayed aspirational

For twenty years after Fowler's 2003 essay, Practice #4 was widely understood but rarely implemented. The economics didn't work:

  • A real per-developer database costs full provisioning — storage, compute, license seats, backup setup, network policy.
  • Production-shaped data is the hard part. A developer database with synthetic / sampled / sanitised data fails to surface bugs that depend on real production volume, real cardinality, real edge cases. A developer database that is a clone of production costs as much as production.
  • DBA cycles are the bottleneck. Even on cloud substrates that could in principle clone a database in minutes, somebody has to run the clone, manage credentials, garbage-collect after the developer is done.
  • Workstation resources don't fit production scale. Running a terabyte-scale Postgres instance on a developer laptop is not an option; running it in the cloud at full size is too expensive to do per-developer.

The 2026 Databricks post canonicalising this gap:

"Practice #4 — Everybody gets their own database instance — has stayed aspirational on most teams because true per-developer production-shaped databases cost time, money, and DBA cycles. The compensating layer that emerged to work around the gap (mock objects, shared staging environments, in-memory database substitutes, DBA ticket queues) became foundational methodology by default, not by design."

(Source: sources/2026-05-29-databricks-enabling-evolutionary-database-development-database-branching-with-lakebase)

The compensating layer existed because of an absent capability, not because the methodology required it. See concepts/database-development-compensating-layer for the bookshelf of mocks / H2 / staging / DBA-tickets that emerged.

What lifts the constraint

The substrate change that finally makes Practice #4 affordable is copy-on-write database branching (concepts/copy-on-write-storage-fork):

  • Branch creation is sub-second even on terabyte-scale databases — no data copy at fork time.
  • Production-shaped data is included by default — the branch is a logical fork of the same storage, so the full production surface is available with all its real cardinality and edge cases. (Subject to PII / governance considerations; see concepts/branch-level-governance-propagation.)
  • Storage cost is incremental — branches pay only for divergent pages, so per-developer-per-feature-branch is bounded by changes rather than full clones.
  • No DBA cycle per branch — the branch is provisioned via self-service API or IDE extension; the DBA is freed from the ticket queue.

The 2026 substrate (Databricks Lakebase, Neon, PlanetScale):

"In 2026, copy-on-write database branching arrives in Databricks Lakebase. A one-second, zero-storage-at-creation branch of a terabyte-scale production database is now an O(1) operation. The constraint that kept Practice #4 aspirational has lifted."

(Source: sources/2026-05-29-databricks-enabling-evolutionary-database-development-database-branching-with-lakebase)

Implications when the constraint lifts

When Practice #4 becomes operational default:

Three properties of the developer-DB instance

The post canonicalising Practice #4's substrate-shift names three load-bearing properties of the developer's database instance, all three of which must hold simultaneously:

Property What it means Failure mode if absent
Fast Created when the developer needs it, not when someone provisions it Developer waits for shared resource; falls back to wishful local stand-in
Realistic Same engine, same schema, same governance, production-shaped data Bugs caught in staging or production rather than during development (H2/SQLite trap)
Isolated Experiments don't interrupt anyone else; can be discarded freely Developer is overly cautious; can't try multiple solutions; afraid to experiment

"Together, those three properties turn database change from a bottleneck into a normal part of feature development."

(Source: sources/2026-05-29-databricks-enabling-evolutionary-database-development-database-branching-with-lakebase)

The historical compensating layers each violate at least one of the three:

  • Mock objects: fast + isolated, but not realistic.
  • H2 / SQLite: fast + isolated, but not realistic (different SQL dialect, different null/constraint semantics).
  • Shared staging database: realistic, but not isolated (collisions); often not fast (waiting for free window).
  • Local Docker Postgres + stale pg_dump: fast + isolated, but only partially realistic (data is stale; production volume + edge cases absent).
  • Cloud VM with full clone: realistic + isolated, but not fast (clone takes hours; cost per developer is high).

Copy-on-write branching is the first substrate where all three hold simultaneously by construction.

Practice #4 vs adjacent practices

Practice What it solves Practice #4's role
#1 DBAs collaborate closely with developers Cultural — same team #4 makes #1 affordable: DBA can pair on a real branch, not gate-keep tickets
#2 Frequent integration to shared master CI / mainline-first development #4 enables this: developers integrate from their branch, not from a long-running fork
#3 Database = schema + test data Reproducibility of database state #4 carries the test-data side: branch includes the production-shaped data
#5 All changes are database refactorings Named, deliberate transformations #4 gives refactorings a sandbox to be tested in
#6 Automate the refactorings Migration scripts, not manual ALTER #4 gives the script a place to be applied + verified
#7 Version-control everything Schema + migrations in repo #4 doesn't depend on this — but composes naturally with same-PR application + migration changes

Seen in

  • sources/2026-05-29-databricks-enabling-evolutionary-database-development-database-branching-with-lakebaseFirst wiki canonicalisation of Practice #4 as the constraint that the 2026 substrate lifts. Databricks 2026-05-29 Tier-3 post (Part 1 of three-part series). Names the practice, explains why it stayed aspirational, names the four-piece compensating layer that emerged in its absence, frames Lakebase's copy-on-write branching as the substrate change that lifts the constraint. Three-property fast/realistic/isolated framing introduced for the developer-DB instance.

  • (Forward reference) Fowler 2003 Evolutionary Database Design is the canonical introduction of Practice #4. Cited by the Databricks post but not separately ingested.

Last updated · 542 distilled / 1,571 read