Migration & Compatibility
Every change to a running system has an initial state, a transition state, a final state and a way back. Backward compatibility, versioning and data migration.
Every change to a running system has an initial state, a transition state, a final state and a way back. The transition state is the one people skip, and it is live in production longest.
Old clients, stored data, in-flight events, published APIs, plugins and databases all constrain what today's change may do. Compatibility is not a property of an API; it is a constraint on every edit.
An explicit version lets old and new consumers disagree about the contract. It also creates a maintenance obligation that lasts as long as the oldest version you have not managed to kill.
Schema, data and application code are three things that must change in a safe order. Getting the order wrong is the difference between a routine deploy and a restore from backup.
Add the new shape, write both, migrate readers, stop writing the old, remove it. The canonical safe sequence, and the reason it works is that every step is individually revertible.
A flag decouples deploying code from releasing behaviour, which is genuinely valuable. It also multiplies the state space of the system and creates a cleanup obligation nobody is measured on.