Skip to content

CONCEPT Cited by 1 source

Schema as code

Definition

Schema as code is the database analogue of Infrastructure as Code (IaC): the schema of a relational database is expressed as a text file in a declarative DSL (HCL, SQL, YAML, Prisma schema language, JSON), checked into version control alongside the application, and materialised into the live database by a tool that compares desired state (the file) to actual state (the live database) and emits the imperative DDL required to reconcile them.

The defining property is that the file is the source of truth, not the live database. The live database is a reconcilable materialisation — running the apply tool against any database (fresh, stale, drifted) brings it to match the file. This inverts the traditional migration model in which a sequence of imperative CREATE / ALTER / DROP statements (Rails migrations, Flyway, Liquibase, ActiveRecord) is authored by operators and applied in order, with the live database being the cumulative result of that sequence.

(Source: sources/2026-04-21-planetscale-declarative-mysql-schemas-with-atlas-cli)

Why the IaC framing matters

Brian Morrison II's PlanetScale 2022 tutorial frames the pattern verbatim: "One of the best things the DevOps movement has ushered in is the concept of Infrastructure as Code. IaC lets you define your infrastructure in specially formatted files, and allows you to use automation tools to create or modify your infrastructure based on those files. But did you know that you can also manage your database schemas in a similar approach?" The IaC analogy is load-bearing: teams that already use Terraform / Pulumi / CloudFormation for infrastructure get the ergonomics of declarative state + diff + apply + Git-versioning for free at the schema layer.

Contrast with imperative migration files

Dimension Imperative migrations Schema as code
Source of truth Cumulative sequence of migration files Single desired-state file
Apply primitive Run all new files in order Compute diff, apply delta
Bootstrap new env Replay all migrations apply against empty DB
Detect drift Not built-in Built-in (inspect reveals it)
Rollback Write a reverse-migration file Revert the HCL file commit
Rename column Author a migration step Edit file; tool infers diff
Dependency ordering Implicit in file order Tool-computed from DAG

Neither is universally superior. Imperative migrations capture the intent of each change (rename, add, split) unambiguously, which is important for tools like Rails where migrations are data operations as well as schema operations. Declarative tools lose this intent-capture (a rename looks like a drop + add unless the tool has special heuristics) but gain drift-detection and multi-environment reconciliation for free.

Git-native implications

"Keeping your database schema under version allows it to have accountability (by configuring Atlas to apply changes on git operations) as well as provides a historical reference to see how your database structure changes over time." (Source: sources/2026-04-21-planetscale-declarative-mysql-schemas-with-atlas-cli)

A schema-as-code workflow puts every schema change in the same review + approval pipeline as application changes: pull request against the HCL file, CI runs the diff, reviewers approve, CI applies. The operational boundary between "infrastructure change" and "schema change" collapses into one flow.

  • patterns/declarative-schema-management — the pattern that instantiates schema-as-code with a specific tool (Atlas, Skeema, Bytebase, Prisma Migrate).
  • concepts/schema-evolution — the broader problem space. Schema-as-code is one altitude of schema evolution (within-service sync-DDL with a declarative tool); other altitudes are Lyft's compile-time Protobuf-design discipline and Datadog's async-CDC runtime registry.
  • patterns/expand-migrate-contract — a sequencing discipline that is orthogonal to schema-as-code. The declarative tool can apply any single step in the expand-migrate-contract sequence (add column, drop column) but cannot orchestrate the full sequence — the operator still authors the intermediate HCL states and applies them in order. The two compose: schema-as-code gives you the apply mechanism, expand-migrate-contract gives you the sequencing discipline.
  • concepts/coupled-vs-decoupled-database-schema-app-deploy — schema-as-code does not resolve the coupled-vs- decoupled question. The HCL file is the database deploy artefact; the application code is still a separate deploy. The two-system-atomicity problem still applies.

Tool ecosystem

  • Atlas CLI — canonical wiki reference implementation (HCL-first, engine-agnostic, open-source).
  • Skeema — MySQL-focused, .sql file as schema DSL.
  • Bytebase — commercial schema-change platform with a GitOps UI.
  • Prisma Migrate (in prisma db push mode) — Prisma-ORM-integrated declarative apply.
  • PlanetScale — the vendor-managed alternative: PlanetScale's native deploy-request + branching + safe-migrations workflow implements the same end goal (safe schema change) with different primitives and vendor-side orchestration. Declarative external tools and vendor-managed pipelines are rivals, not complements.

Seen in

  • sources/2026-04-21-planetscale-declarative-mysql-schemas-with-atlas-cli — canonical wiki introduction of schema-as-code via Brian Morrison II's 2022 PlanetScale tutorial using Atlas CLI. Walks through atlas schema inspect → HCL file → edit → atlas schema apply with operator-in-the-loop confirmation. Frames the pattern as "Database as Code" and draws the IaC analogy verbatim. Flags PlanetScale's safe migrations feature as a must-disable precondition for using Atlas against PlanetScale — canonical datum that declarative tools and vendor- managed schema-change pipelines cannot run simultaneously.
Last updated · 347 distilled / 1,201 read