Keeping the previous application version available is only part of a rollback plan. The previous version must also remain able to understand the state created while the new version was running.
Imagine a hypothetical service replacing a text status with a structured status object. The new application writes the object successfully. An operational problem prompts a return to the old application, which expects text. Traffic has moved back, but the old reader can no longer process some records.
The decisive moment was the first incompatible write. Before that point, switching versions may have been straightforward. After it, recovery needs a way to interpret or transform the new data. Deployment diagrams often make the traffic switch prominent while leaving this transition implicit.
Parallel Change, described by Danilo Sato, offers a useful pattern: expand the interface, migrate its consumers and contract it after the transition. For a stored representation, that can mean introducing a new field while retaining the old one, moving readers and writers in stages, then removing the old representation once it is no longer needed.
The exact sequence depends on the application. Writing both representations can introduce inconsistencies if one write succeeds and the other fails. A backfill can race with live updates. Keeping two fields is therefore a temporary compatibility mechanism with a consistency problem to solve, not an automatic guarantee of safety.
Define an authority rule during the transition. Which representation should a reader trust if the two disagree? How are new writes distinguished from backfilled records? Can an old reader encounter a value it cannot represent? These questions determine whether the compatibility window is real.
Message schemas have related concerns. The Protobuf evolution guide separates changes that preserve binary compatibility from changes that are unsafe or conditional. Even a compatible field addition needs application behavior for readers that do not know the field. A successful parse cannot show that an old application handles a newly introduced state.
A rollback exercise should use data produced by the new version. Start with synthetic records, run new writes, then invoke the old reader and verify meaningful results. Merely starting the old binary proves little about its ability to resume service. Include background jobs and exported records if they also consume the changed representation.
The compatibility window should have an explicit end. Retaining every old representation indefinitely creates maintenance work and makes future changes harder to reason about. Removing it too early eliminates a recovery option. Record the conditions under which contraction becomes acceptable, including which readers still exist.
Further learning lies in rehearsing that boundary. For a small stateful service, identify the first write that makes an old reader fail and redesign the migration to delay it. That point often explains the recovery risk more clearly than the choice of deployment platform.