Legacy and migration

5 min read

Expand–Contract: How to Change a Data Schema Without One Shared Cutover Day

Dangerous migrations often require databases, services, and clients to switch at the same time. Expand–Contract turns that into compatible stages: expand first, migrate consumers, then remove the old path.

What problem are we solving?

The more consumers a table, event, or API has, the more dangerous a breaking change becomes. If a renamed field or new structure requires one coordinated switch, the release becomes an organizational operation.

The core problem is not the migration itself. It is the need to synchronize too many independent parts at one moment.

How Expand–Contract works

During expand, the system supports both the old and new ways of working. A new field, contract, or structure is introduced while the old one remains available.

Consumers then move gradually. Only after the old path is truly unused does contract begin and the obsolete structure is removed.

One large risk becomes several smaller observable steps that can be paused independently.

What the business gets

The main benefit is fewer releases that require one shared date and heavy coordination. Teams can migrate on their own cadence, and a critical change does not have to become a company-wide event.

Downtime risk from incompatibility falls and individual steps are easier to reverse. That matters when a synchronized cutover can interrupt revenue or operations.

What the team gets

Teams gain a temporary compatibility window. They can prepare infrastructure, move reads and writes, observe behavior, and remove the old path only after confidence is high.

The trade-off is discipline: old-contract usage must be measured, transition states must be tested, and someone must finish the cleanup.

What the customer gets

Customers see fewer technical windows and fewer forced simultaneous upgrades. External partners can move within an agreed migration period instead of one overnight deadline.

What we pay for

The system is temporarily more complex. Two fields, formats, or processing paths may exist at once, and both need testing and consistency controls.

If the contract phase is repeatedly postponed, temporary compatibility becomes permanent legacy.

When it is not needed

If the change is local and has one controlled consumer, a staged migration may be unnecessary. Sometimes one atomic change really is cheaper.

The pattern becomes valuable when updating every consumer at once is impossible or too risky.

What to ask before deciding

In the end

Expand–Contract does not make migration free. It changes the shape of the risk: the company pays for temporary compatibility instead of one large cutover.

For the business, that is often a good trade — some extra engineering work now in exchange for avoiding a single day when one mistake can break everyone.