Backend Development 7 min read

Database Migration Strategies with Feature Toggles: Code‑First, Data‑First, Big Bang, Expand‑Contract, and Double‑Writing

The article explains various database migration approaches—including code‑first, data‑first, big‑bang releases, expand‑contract migrations, and double‑writing with dark reads—highlighting how feature toggles influence compatibility and safety during production system changes.

Continuous Delivery 2.0
Continuous Delivery 2.0
Continuous Delivery 2.0
Database Migration Strategies with Feature Toggles: Code‑First, Data‑First, Big Bang, Expand‑Contract, and Double‑Writing

When changing software in a production system, it is essential to consider shared persistent data, ensuring that the existing database schema remains compatible with newly deployed code, which often requires a database migration.

Although the topic was covered in detail in "Continuous Delivery 2.0," this article briefly reviews several methods to coordinate code deployment with the corresponding database migration.

1. Code‑First

Deploy the new code first, which demands that the new code be compatible with the current database schema.

2. Data‑First

Perform the database schema migration first, requiring that the new schema still satisfy the compatibility needs of the old code.

3. One‑Time (Big Bang Release)

This traditional approach stops the system, upgrades the database schema and deploys the new code, then restarts the system. Compatibility concerns are ignored, but feature toggles introduce extra challenges because data must remain compatible with both old and new code paths while the system is offline.

4. Expand‑Contract Migration

When code changes that use feature toggles also require data‑structure changes, the migration is performed as a series of backward or forward compatible steps. First, a data‑first change expands the schema (e.g., adding a new table and nullable foreign key). Then a code‑first change writes to both the old and new structures. After back‑filling data and removing nullability, a final code‑first change contracts the contract by making the new structure read‑only and dropping the old columns.

Example: an e‑commerce system normalizes the shipping address from columns in the Orders table to a separate ShippingAddress table, using a feature toggle to manage the transition.

The migration steps are:

Data‑first: add ShippingAddress table and nullable shipping_addr_id foreign key; no code change.

Code‑first: modify code to write to both the old shipping address column and the new table.

Data migration: back‑fill the new table, create rows for existing orders, link via foreign key, and make the foreign key non‑nullable.

Contract: make the new table read‑only in code and drop the old shipping address column.

5. Double‑Writing and Dark Reading

During the intermediate phase, the system must support both old and new models. Double‑writing writes to both locations whenever a shipping address is created or updated. Dark reading reads from both sources and compares results to ensure consistency, providing confidence and an easy rollback path via the feature toggle.

6. Summary

Feature toggles and migration techniques such as expand‑contract and double‑writing are preferred over big‑bang releases for safe incremental data migration. Dark reading helps verify correctness, while very large database changes may still require traditional planning and change control.

backendDeploymentfeature-toggledatabase migrationbig bang releaseexpand-contract
Continuous Delivery 2.0
Written by

Continuous Delivery 2.0

Tech and case studies on organizational management, team management, and engineering efficiency

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.