Course contentsShow
← Databases & SQL
Lesson 1910 of 1,95318. Application Integration PatternsFree lesson

Zero-Downtime Schema Evolution

Apply the expand-contract pattern to update database schemas without requiring application outages.

In this lesson, you will learn how to evolve your database schema without forcing a maintenance window by employing the Expand-Contract (Parallel Change) pattern.

When you need to modify an existing schema—such as renaming a column or changing a data type—a traditional ALTER TABLE can lock your production tables, causing an application outage. To avoid this, we decouple the schema change from the code update by breaking the operation into smaller, compatible phases.

The Expand-Contract Strategy

Instead of performing a destructive ALTER, follow these three distinct phases:

  1. Expand: Add the new schema element (e.g., a new column) alongside the old one. Update your application to write to both the old and new columns, while continuing to read from the old one. Backfill the new column with data from the old one in the background.
  2. Migrate: Once the data is synced, update your application to read from the new column.
  3. Contract: After verifying that the application is successfully using the new schema and performance is stable, remove the old, redundant column.

Practical Example: Renaming a Column

Imagine you want to rename user_name to username. A direct rename would break all existing application instances.

Phase 1 (Expand): Add the new column:

ALTER TABLE users ADD COLUMN username VARCHAR(255);

Configure your application to write user_name to both columns. Perform a background migration to copy existing user_name values into username.

Phase 2 (Migrate): Update your application logic to read from username. At this point, the application ignores user_name for business logic, though it may still perform dual writes.

Phase 3 (Contract): Once the application is fully transitioned, drop the old column:

ALTER TABLE users DROP COLUMN user_name;

By ensuring that each step is backward-compatible—meaning the existing code remains functional throughout the process—you eliminate the need for a global "stop-the-world" deployment. This pattern allows you to iterate safely, even across multiple deployment cycles, ensuring your database evolves in lockstep with your application without ever interrupting service.

Key Takeaway: Never perform destructive schema changes in a single step; use the Expand-Contract pattern to ensure your database remains compatible with your application code at every stage of the transition.