
Changing your backend without breaking old versions of your app.
Someone is always using an older version of your app, so every change to the server or database feels like it might break someone, and teams that feel that freeze up and ship nothing. This is the standard way out.
You already know this problem. A backend change (a renamed field, a new rule, a slightly different response) works for the newest version of the app and breaks it for everyone still on an older one. So the safe move becomes making no change at all. Do that enough times and the whole roadmap freezes: the team ships small, cosmetic things and leaves the backend and the database untouched, because nobody can promise a change won’t break someone.
the problem
You can’t make everyone update.
And that one fact quietly breaks a lot of apps.
Change the way your app and your server talk to each other, and you would need every phone on earth to update at the very same moment. That never happens. People skip updates. Old phones can’t run the newest version. The app store takes days to approve a release. So at any moment, many versions of your app are alive at once, all talking to one server.
The server learns the new way of talking. The old apps still speak the old way. Their messages stop lining up. Buttons do nothing. Screens go blank. Orders fail to go through. To someone who did nothing wrong, the app simply broke, and they have no idea why.
The usual fix works once. Then it rots.
The quick patch is to teach the server both ways: a little if old, do this; if new, do that in every spot where they differ.
// in orders.ts, and the same tangle everywhere else if (version <= 3) return oldOrderShape(o); else if (version === 4) return orderShapeV4(o); else if (version === 5) return orderShapeV5(o); else if (version < 8) return patchLegacyTax(o); else return newOrderShape(o); // now repeat this in customers.ts, cart.ts, profile.ts...
One change is fine. But you make another, and another. Soon every file is full of these forks. Nobody can tell which ones are still needed, so nobody dares delete them. The pile only grows. That is the part that doesn’t scale: not the writing of it, but the never being able to clean it up.
The customer feels an app that is flaky and forgetful: broken screens, lost work, endless “please update” nags. They don’t know the reason. They just quietly trust it less, and some of them leave.
The product owner feels every release turn risky. A new feature might break the old apps, so shipping slows to a crawl. No one wants to touch the database. “We can’t remove that yet, someone might still be on the old version” becomes a permanent excuse, and the team spends its days babysitting old code instead of building new things.
There is a cleaner way: one place to handle old and new, instead of a thousand.
how apps and servers get along
Old phones, new phones, one computer.
A trick that sounds fancy but really isn’t.
Your app is on lots of phones. Some people update it. Some don’t. So old apps and new apps all talk to the same computer at once.
The old app talks in an old way. The new app talks in a new way. You don’t want the computer to keep track of both. That gets messy fast.
So you put a translator at the front door.
A message comes in. The translator turns old talk into new talk. Now the computer only ever hears the new way. It does its job and answers. On the way back out, the translator turns the answer into old talk again. The old phone gets it. The new phone gets it. The computer only ever learned one way.
There is also a guard at the door. If an app is way too old to help, the guard stops it and says: update first. That guard is the thing that lets you throw old stuff away later.
The phone
Talks one way, and says which way at the top of every message.
The guard
Too old to help? Turned away, go update. Everyone else walks in.
The translator
Flips old talk to new on the way in, and new back to old on the way out.
The computer
Only knows the new way, and so does the place it keeps everything.
The messy part lives in one small spot.
Not smeared all over your code. When nobody is on the old app anymore, you toss that one little note, and everything stays tidy.
now watch one message make the trip
See it happen.
Pick who is sending, then step through.
Who is sending the message?
A couple of app versions behind. It still speaks the original name format.
Press Send the message to start.
logs