Standalone conceptPatternChapter III · Evolution · Building block 13 of 15

Expand and contract

A simultaneous contract change can make running old and new versions incompatible.

  1. ExpandExpand: The new interface remains compatible with the old one.
  2. MigrateMigrate: Consumers and data move incrementally.
  3. ContractContract: The old form is removed after usage is verified.

Context

Why this is important

Keep contract changes compatible during incremental delivery.

Keep contract changes compatible during incremental delivery.

Shop example · Mapping

Expand-Contract: inspect the decision

The shop example uses the existing shared database and seven modules. Any added service or deployment model is a hypothetical extension. The shop needs to replace `delivery_note` with `shipment_reference`. First, a database migration adds the new column and the application reads both fields. In the next release, it writes both values and a background job backfills existing orders. Metrics show all instances using the new column; a later contract release removes the old one. This permits rollback during migration and separates the destructive change from the first deployment.

This is how you read the picture

  1. Expand Expand
  2. Migrate Migrate
  3. Contract Contract
Expand-Contract: inspect the decision
ConceptMeaningReview question
ExpandThe new interface remains compatible with the old one.Which step fills `shipment_reference` for existing orders?
MigrateConsumers and data move incrementally.Which evidence permits the contract step?
ContractThe old form is removed after usage is verified.Why is deletion of the old field in a later release?
Während der Übergangszeit müssen alte und neue Anwendungsversionen mit dem gemeinsamen Vertrag arbeiten können. Rückwärtskompatibilität, Datenabgleich, Messung verbliebener Altzugriffe und ein klarer Abschluss verhindern, dass die Übergangsphase zum Dauerzustand wird. Use the questions in the second column to test this scenario.

Benefits & limitations

Helps if:

  • Keep contract changes compatible during incremental delivery.
  • Plan expand, migration, and contract as separate verifiable steps.

Boundaries

  • Parallel operation temporarily increases complexity and must be actively completed.
  • Destructive contract steps must wait for all old readers, writers, jobs, and rollback versions.

In practice

  1. Add `shipment_reference` compatibly and read both columns; check that old and new application instances process the same orders during the first release.
  2. Then enable dual writes and background migration, compare row counts and values, and monitor errors until all instances reliably use the new field.
  3. Remove `delivery_note` only in a later contract release after verifying backup and rollback paths; document the metric that supports this release decision.
Read the detailed explanation

Expand-contract splits an incompatible schema or interface change into compatible releases. First the new form is added, then consumers and data move in a controlled way, and finally a contract step removes the obsolete form.

During transition, old and new application versions must both work with the shared contract. Backward compatibility, data reconciliation, measurement of remaining old access, and a clear finish prevent the transition from becoming permanent.

The shop example uses the existing shared database and seven modules. Any added service or deployment model is a hypothetical extension. The shop needs to replace `delivery_note` with `shipment_reference`. First, a database migration adds the new column and the application reads both fields. In the next release, it writes both values and a background job backfills existing orders. Metrics show all instances using the new column; a later contract release removes the old one. This permits rollback during migration and separates the destructive change from the first deployment. datenmigration and deployment help compare this decision with adjacent concerns.

Check your understanding

Test yourself in three stages

  1. ReadingCheck in the picture

    Which step fills `shipment_reference` for existing orders?

    View the solution with justification

    A background job after both fields are written in parallel.

  2. ApplyingTransferred to a new situation

    Which evidence permits the contract step?

    View the solution with justification

    Metrics show no old readers or writers remain, including jobs and rollback versions.

  3. EvaluateWeighing an alternative

    Why is deletion of the old field in a later release?

    View the solution with justification

    So old and new application versions remain compatible during migration and rollback.

Continue on the learning path

Next in Evolution & assessment: Distributed Monolith.