Feature Flags for Database Migrations: Ship Schema Changes Without Downtime
Database migrations are the part of a deployment that keeps engineers up at night. Code can be rolled back in seconds — schema changes often can't.
The usual approach — migrate the schema and deploy the new code simultaneously — is a single point of failure. If anything goes wrong, you're choosing between data integrity and availability. Neither option feels good at 2am.
The Problem with Coupled Migrations
When you deploy new code and a schema change at the same time, your deployment window is the danger zone. Old application instances running against the new schema, or new code hitting old columns — both situations cause failures that are hard to diagnose and painful to undo.
This gets worse as teams scale. Multiple services reading the same database. Rolling restarts that leave mixed versions running side-by-side. Blue-green deployments where the cutover touches schema that both environments share. The coupling between code and schema is a liability.
The Expand-Contract Pattern
The expand-contract pattern solves this by making schema changes strictly additive before removing anything. Combined with feature flags, it gives you a safe, incremental path through any migration:
- Expand: add the new column, table, or index — no existing code breaks because nothing reads or writes it yet.
- Flag-gate the new path: deploy code that writes to both old and new schema, but reads only from the old. The flag is off.
- Backfill: migrate existing data into the new structure.
- Ramp the flag: enable reads from the new schema for 1%, then 10%, then 100%.
- Contract: once the flag is fully rolled out and stable, clean up the old column in a follow-up migration.
At every step, rolling back means flipping a flag — not reverting a schema change.
What This Looks Like in Code
Using the Featureflow Node.js SDK, the flag-gated read path is a single conditional:
import featureflow from 'featureflow-client';
const client = featureflow.createClient({ apiKey: process.env.FF_API_KEY });
await client.waitForInitialization();
async function getUserEmail(userId: string): Promise<string> {
const context = { key: userId };
if (client.evaluate('new-email-column', context).isOn()) {
// Read from new normalised column
return db.users.findEmail(userId);
}
// Fallback to legacy denormalised field
return db.legacy_users.findEmailField(userId);
}Both code paths run in production. The flag controls which one serves traffic. If the new column has a data quality issue at 10% rollout, you disable the flag and 100% of users instantly fall back — no migration needed, no incident.
Observability During the Ramp
The incremental rollout is only useful if you're watching what changes. Tag your database query metrics with the flag variant so you can compare error rates, latency, and result counts between old and new paths side-by-side. Featureflow's percentage rollout controls let you pause at any stage if metrics drift before committing to 100%.
The contract phase — removing the old column — becomes a no-stakes cleanup rather than a high-risk operation. By that point the old path has had zero traffic for days or weeks.
Schema changes don't have to be deployment-day drama. The expand-contract pattern with feature flags turns one dangerous big-bang migration into a series of boring, reversible steps.
👉 See how Featureflow handles percentage rollouts and environment targeting at featureflow.com.
#FeatureFlags#DatabaseMigrations#ContinuousDelivery#ZeroDowntime#DevOps
Ship schema changes without the fear
Featureflow gives you percentage rollouts, instant kill switches, and environment targeting — free to start.
Start Now (Free)Related Articles
Feature Flags for Mobile Apps: Ship Without Waiting on App Store Review
App store reviews take days. Bugs don't wait. Feature flags let mobile teams ship code continuously, gate features remotely, and kill broken behaviour — without a new release.
Feature Flags and Observability: How to Know If Your Rollout Is Working
Releasing to 10% of users without watching metrics is just gambling at a smaller scale. Here's how to connect flag evaluations to your observability stack — so you know when to expand, and when to pull back.
Feature Flags for Customer Targeting: Roll Out Features to the Right Users
Percentage rollouts control how many users see a feature. Targeting rules control which users see it — by plan tier, beta opt-in, org ID, or any attribute you pass. Here's how to use them.