Backward compatibility in software development is an important concept that is often overlooked, especially in legacy systems. This leads to stressful software updates and regression bugs. But it’s usually not so difficult to avoid these horror scenarios.
If you’re unfamiliar with the concept, backward compatibility means making sure a new version of software keeps working with the current version of an external system.
Backward compatibility is important when you’re going to update your software. In this day and age, it’s very likely that your software integrates with other systems like a database or a service from another team or company.
When the new version of your software makes calls to or accepts calls from this system in a way that requires that system to change as well, then you have a “breaking change.”
If however, you make sure your update can work with both the new and the old way of making/accepting calls, then you’re backwards compatible.
If you’re going to introduce a breaking change, you’ll have to coordinate releases. The update to system A will have to be done simultaneously with the update to system B.
This is a risky situation.
First, it’s difficult to coordinate releases. Especially, if another company is involved. Even more so, if you’re in different time zones.
But it’s also stressful because things can go wrong easily. And when they do, it’s difficult to fix the situation. If there’s a bug in the integration, both systems might need to be fixed, requiring even more coordination. Stress leads to frustration, which leads to angers, which leads to bad relationships.
It’s even worse if one system needs to be rolled back for whatever reason. Then the other needs to be rolled back as well. This might not always be possible, because the new version may have side effects that can’t be undone: new data structures, emails sent, lost data, etc.
So how can you perform updates that involve breaking changes? Well, you don’t. You make your updates backward compatible.
Actually, you can perform breaking changes, you just do it in two steps. First, you update a system to a state that it works with both the old and the new way of integrating:
Then you leave some time for the external system to start using the new way:
When it has switched, you can safely drop support for the old way of integrating:
This removes all stress from deploying a breaking change (though not necessarily from the release itself). And it requires little coordination, just some communication about the timeline for the two steps.
Breaking Changes In Legacy Systems
Legacy systems are often plagued with regression bugs: bugs that occur after every new release, even though the features worked fine before. In legacy systems it’s important to reduce risks as much as possible. Avoiding breaking changes is one important technique to do so.