Skip to content
lorebow

Dev/prod parity

Keep development, staging and production as alike as possible, so code that works on your laptop works in production.

KFounder and editor 177 words 1 min read Find it on the map
On this page

Keep development, staging, and production as similar as possible. Most "works on my machine" bugs come from a gap between where code is written and where it runs. Twelve-factor names three gaps, and closes each one.

GapTraditional appTwelve-factor app
Time between writing code and deploying itWeeks or monthsHours or minutes
Personnel: who writes it and who deploys itDevelopers write, ops engineers deployThe developers who wrote it deploy it and watch it run
Tools in development and productionSQLite and a laptop; Postgres and Linux in productionThe same database, versions and OS in both
A change on its way to productionPostgres 16 everywhereStep 1 of 3
LaptopPostgres 16, DockerCIsame imageStagingPostgres 16ProductionPostgres 16Youwrote it, ship it

1.Close the tools gap

Development runs the same Postgres version as production, in a container, instead of a lighter substitute.

#Use the real backing services locally

It's tempting to use SQLite on your laptop and Postgres in production, because SQLite needs no setup. But they differ in types, locking and SQL, and those differences surface as production-only bugs.

Containers make the real thing almost as easy:

compose.yamlyaml
services:
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: devpassword
    ports: ['5432:5432']
  cache:
    image: redis:7
    ports: ['6379:6379']
bash
docker compose up -d
export DATABASE_URL=postgres://postgres:devpassword@localhost:5432/postgres

Pin the same major versions you run in production, and update both together.

Tests pass against SQLite on your laptop, then a query fails in production on Postgres. Which gap caused it?

Referenced by