PlanetScale — Declarative MySQL schemas with Atlas CLI¶
Summary¶
Short PlanetScale tutorial post by Brian Morrison II
(2022-09-16, re-surfaced via the 2026-04-21 feed snapshot)
demonstrating how to use Atlas CLI
(atlasgo.io) — a third-party
open-source schema-management tool — to apply a
declarative / "Database as Code" workflow against a
PlanetScale MySQL database. The
post frames declarative schema management as the database
equivalent of Infrastructure as Code (IaC): write the
desired end-state of the schema in a file, let the tool
diff against the live database, apply the delta. Walks
through atlas schema inspect -u <CONN> > schema.hcl to
extract the current database schema into HCL, edits the
HCL to add a description column to a hotels table, and
atlas schema apply -u <CONN> -f schema.hcl to materialise
the change — Atlas computes the diff ("Planned Changes:
Modify hotels table … ALTER TABLE … ADD COLUMN
description varchar(100) NOT NULL") and prompts the
operator to confirm before execution. Closes with a
PlanetScale-specific operational warning: "when using
Atlas with PlanetScale, you'll need to make sure you don't
turn on safe migrations, as that will prohibit you from
running DDL on production." The tutorial is the canonical
wiki instance of the declarative-schema-management
pattern in its simplest form — no Git integration, no CI
pipeline, no drift-detection loop, just the two-command
inspect-then-apply workflow.
Key takeaways¶
- Schema is code, file is truth. Atlas keeps the
representation of the database schema in a file
(
.hclby convention, JSON also supported). The operator edits the file, not the database directly; the tool reconciles the live database against the file as the source of truth. "Atlas CLI is a command line tool that helps manage the structure of your database by keeping a representation of the schema in a file." Canonical declarative- schema-management shape: declarative desired state file → tool-computed diff → imperative engine-level DDL applied. (Source: article §"Atlas CLI".) atlas schema inspectbootstraps from an existing database. A greenfield Atlas workflow does not require starting from a blank schema file — point the CLI at a running database and it emits the HCL file matching the current state. "Atlas makes it easy to apply a 'Database as Code' approach to an existing database by generating a file representing the schema of that database." The emitted HCL contains per-column type + nullability + default + auto-increment attributes, primary-key declaration, and schema-level charset + collation (utf8mb4+utf8mb4_0900_ai_ciin the worked example — the MySQL 8 defaults canonicalised on concepts/character-set + concepts/collation).- Connection string carries provider specifics.
Atlas accepts a MySQL-protocol connection URL of the
shape
mysql://<user>:<pass>@<host>/<db>?tls=truewheretls=trueis PlanetScale-required for TLS-enforced endpoints. Same URL format works for any MySQL endpoint — Atlas is intentionally engine-aware but vendor-agnostic. atlas schema applycomputes and applies the diff. Atlas re-inspects the live database, compares against the HCL file, prints the imperative DDL it intends to run, and promptsApply / Abort. Example output in the post:Operator-in-the-loop confirmation is the default; non-interactive-- Planned Changes: -- Modify "hotels" table ALTER TABLE `hotels_db`.`hotels` ADD COLUMN `description` varchar(100) NOT NULL Use the arrow keys to navigate: ↓ ↑ → ← ? Are you sure?: ▸ Apply Abort--auto-approveis available for CI/CD integration ("It can be used by itself to manage your schema changes, or as part of a CI/CD pipeline to automate the process of updating your schema based on the definition file.").- PlanetScale-specific incompatibility: turn off safe migrations. PlanetScale's built-in "safe migrations" feature blocks direct DDL against production and instead routes schema changes through PlanetScale's deploy-request + branching UI. Using Atlas against a PlanetScale branch requires disabling safe migrations because Atlas operates by issuing DDL directly over the MySQL protocol. "when using Atlas with PlanetScale, you'll need to make sure you don't turn on safe migrations, as that will prohibit you from running DDL on production." Canonical trade-off datum: declarative tools and vendor-managed schema-change pipelines are rivals, not complements — the customer picks one ceremony, not both. PlanetScale's native deploy- request workflow (branching + non-blocking schema changes + safe migrations) and Atlas's declarative workflow (HCL file + diff
- apply) implement the same end goal (safe schema change) with different primitives.
- Version-controlling the HCL file is the IaC
analogue. "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." Git-for-schema is the natural
next step — every commit to the HCL file is an
auditable schema-change record; diffing
HEAD~1againstHEADanswers "what changed?" before the CLI even runs.
Systems named¶
- Atlas CLI — third-party open-source (atlasgo.io) schema- management tool from Ariga. First canonical wiki mention. Engine-agnostic across MySQL, Postgres, MariaDB, SQLite, SQL Server, ClickHouse; HCL-first schema DSL with JSON fallback; supports versioned and declarative migration modes.
- PlanetScale — target MySQL endpoint.
- MySQL — engine.
Concepts named¶
- Schema as code —
first canonical wiki treatment. The database
equivalent of Infrastructure as Code: the schema is
expressed as a text file in a declarative DSL (HCL,
SQL, YAML), versioned in Git, and applied by a tool
that diffs the desired state against the live
database. Contrast with imperative migration files
(Rails/ActiveRecord/Flyway/Liquibase — sequences of
CREATE/ALTER/DROPsteps executed in order).
Patterns named¶
-
Declarative schema management — first canonical
wiki pattern. The four-element shape: (a) desired-
state file in a schema DSL; (b) inspect/dump
primitive to bootstrap the file from an existing
database; (c) diff engine that computes the DDL
needed to move the live database to the desired
state; (d) apply primitive that executes the DDL
(with optional operator-in-the-loop confirmation).
The file is source of truth; the database is a
reconcilable materialisation. Atlas, Skeema, Bytebase,
and Prisma Migrate (in
prisma db pushmode) are the canonical implementations; the post documents the simplest of the four (Atlas, two-command flow).
Operational numbers¶
None in the post. No benchmarks, no diff-computation latency, no schema-size limits, no production retrospective. This is a tutorial, not a production war story.
Caveats¶
- Tutorial voice, not production retrospective.
Brian Morrison II is developer-advocacy / educational,
not PlanetScale / Ariga core engineering. The post
demonstrates the happy-path two-command flow against
a fresh
hotelstable with four columns; it does not cover destructive diffs (column renames, type changes that force rewrite), multi-schema apply, foreign-key handling, migration-file mode (Atlas also supports versioned migrations as a separate operating mode), Atlas's policy/lint engine, CI/CD integration specifics (beyond mentioning it is possible), or rollback. Real production use of declarative schema management requires engaging with every one of these. - No diff-computation internals. The post does
not explain how Atlas computes the diff (parse both
sides into an AST and tree-diff? use
INFORMATION_SCHEMAintrospection on the live side? how does it handleINSTANT/INPLACE/ online- DDL algorithm selection? does it know about MySQL'sALGORITHM=INSTANToptimisations added in 8.0.12?). - No conflict with PlanetScale's own schema machinery analysed. The post flags that "you'll need to make sure you don't turn on safe migrations" but does not discuss the operational trade-offs between Atlas's declarative ceremony and PlanetScale's branching + deploy-request ceremony. They overlap substantially (both target safe schema change) and the customer cannot run both simultaneously — but the post does not recommend one over the other, and does not explain when a team would prefer Atlas over PlanetScale-native tooling (hint: cross-vendor portability + Git-native workflow + less vendor lock-in).
- Pedagogy from 2022. PlanetScale's own schema machinery has evolved substantially since 2022 (see the 2026-04-21 [[sources/2026-04-21- planetscale-behind-the-scenes-how-schema-reverts- work|Schema reverts]] post and [[sources/2026-04-21- planetscale-announcing-vitess-21|Vitess 21 release notes]] for the current state of Online DDL
- Instant-DDL +
schemadiff). The Atlas CLI-on- PlanetScale story from 2022 predates most of that machinery. - MySQL 5.7 era charset defaults. The emitted HCL
shows
charset = "utf8mb4"+collate = "utf8mb4_0900_ai_ci"— MySQL 8 defaults (see concepts/utf8mb4-vs-utf8). On an older MySQL 5.7 PlanetScale deployment the defaults would differ. - No contradiction with existing wiki claims. Declarative schema management (this post) and expand- migrate-contract (2026-04-21 Taylor Barnett post) are complementary, not conflicting: the declarative tool knows how to turn a desired-state file into DDL, but the sequencing of the underlying change (add column → dual-write → backfill → switch reads → drop column) is still the operator's responsibility. Atlas can apply any single step in the expand-migrate-contract sequence, but cannot orchestrate the entire sequence by itself — the operator must author the intermediate states of the HCL file and apply them in order.
Source¶
- Original: https://planetscale.com/blog/declarative-mysql-schemas-with-atlas-cli
- Raw markdown:
raw/planetscale/2026-04-21-declarative-mysql-schemas-with-atlas-cli-f9900e3b.md
Related¶
- systems/atlas-cli — Atlas CLI system page.
- systems/planetscale — target managed-MySQL vendor.
- systems/mysql — engine.
- concepts/schema-as-code — the database- equivalent-of-IaC concept this post canonicalises.
- concepts/online-ddl — the engine-level primitive Atlas ultimately invokes.
- concepts/coupled-vs-decoupled-database-schema-app-deploy — Atlas's apply-step is the database deploy; the operator still owns the application deploy sequencing (see patterns/expand-migrate-contract).
- concepts/schema-evolution — declarative tools sit inside the wider schema-evolution problem space.
- patterns/declarative-schema-management — the pattern this post canonicalises.
- patterns/expand-migrate-contract — complementary pattern; declarative tools execute a single apply step, the sequencing of multi-step schema evolution is still the operator's.
- companies/planetscale — vendor company page.