Build the safeguards
Eight explained steps, a source example and a checkpoint at each decision.
Read the tutorialDelivery / Database migrations / Infrastructure as code
A new application wants a renamed field. The old application still reads the original. Release both through a compatibility window and find out whether rollback can actually work.
During a release, old and new application versions may share one database. A compatible migration lets both work until the old readers and writers have been retired.
Actual PostgreSQL executes the migration and client reads. Traffic and readiness phases are an explicit browser model. The download includes a real loopback HTTP switch and a local-only Terraform plan exercise; no cloud deployment is started from this page.
Your independent testing environment
Run the column-rename example. Watch an old client fail after a destructive change. Then compare expansion, backfill and dual writing. The other presets test a failed canary and an early attempt to remove the old column.
Compare a destructive rename with expansion, backfill and compatible reads.
Ready. Choose an example and run both implementations.
All safeguarded data reads return 200 across mixed versions and application rollback. The destructive path produces missing-column errors. The contract gate refuses to remove a column while an old reader remains.
Open the exact source behind this edition. The viewer checks each file against its SHA-256 manifest and explains the decision it implements.
Eight explained steps, a source example and a checkpoint at each decision.
Read the tutorialUnderstand where each pattern helps and which tradeoffs remain.
Compare approachesDownload the independent environment, run the native checks and try a specific extension.
Open the how-to guideStart with Run and read the comparison. The tutorial introduces the code after you have seen the behavior. The how-to guide separates a no-install route from the native developer exercise.
Reset discards this lab’s temporary state and cancels or terminates its pending work. These examples use invented records. No account, production data or cloud deployment is needed.
Actual PostgreSQL executes the migration and client reads. Traffic and readiness phases are an explicit browser model. The download includes a real loopback HTTP switch and a local-only Terraform plan exercise; no cloud deployment is started from this page.
Lab discussion / Safe Rollout Lab
Ask about the code, compare an approach, or describe an edge case. Reader comments are reviewed before publication.
Code walkthrough
These short excerpts connect the lab’s behavior to its implementation. Each example links to the full tutorial step for its context, tradeoffs and checkpoint. Names and dependencies belong to that source; the excerpts are not standalone programs.
Add the new field while keeping the old one. This gives new code somewhere to read without breaking existing consumers. The right production DDL strategy also depends on locking, table size, defaults and the database version; this tiny table demonstrates compatibility only.
ALTER TABLE profiles ADD COLUMN display_name text;
Copy existing values, then maintain both representations during the transition. A one-time backfill is insufficient if an old writer continues changing only the old field. This exercise’s compatible writer sets both fields; the extension challenge deliberately introduces an old writer.
UPDATE profiles SET display_name=full_name;
UPDATE profiles SET full_name=$1,display_name=$1 WHERE id=$2;
The readiness preset marks the canary unready. The browser models the traffic decision, while its data reads remain real. A production readiness probe must reflect the dependencies required to serve safely; a process merely listening on a port may not be sufficient.
if (!canaryReady) keepTrafficOnVersionOne();
The local exercise starts a real loopback HTTP service, switches its query to version two, then switches back after an injected readiness failure. It retains the expanded schema. Reverting an application does not automatically undo a migration or restore removed data.
activeVersion = 1; // retain the expanded schema
The old field may be removed only after old readers and writers are gone and backfill is complete. The gate explicitly checks all three. Production evidence may come from deployment inventory, job configuration and observability; the browser’s consumer count is a reviewed fixture.
oldReaders === 0 && oldWriters === 0 && backfillRemaining === 0