Backward vs. Forward Compatibility

Steven Heidel
6 min readAug 11, 2020

When building a client-server application, the client and server need to agree on how to talk to each other. For instance, if sending JSON, then the client and server have to agree on field names and data types. For databases, the concept is similar; without a schema, the only information you could get back would be an ordered bag of values. Values are meaningless without context.

It’s easy to build the first version when the application is still in development. Coming up with an agreement on the fields and types of data is relatively straightforward. You can break things without consequence until it works. But, the initial version of your application will only last so long. Eventually, you will need to change the data to support new features or remove unsupported ones. This is called evolving a schema.

The naive approach to evolving a schema would be to simply make arbitrary changes and update everything at once. This is impractical for production applications unless you are okay with your product breaking. Let’s say you make an incompatible change like renaming a column in the database from “productNum” to “productId”. After migrating the database to “productId”, the existing application will still be looking for “productNum”. When it doesn’t find a column with that name, it breaks.

A better way would be to make only compatible changes where different systems that talk to each other can be deployed in any order. In the above example, instead of renaming the column, create an alias to the old name so that either would work.

It can be challenging to understand which kinds of changes are compatible and which ones are incompatible. Further complicating things is that there are two different categories of compatibility: backward compatibility and forward compatibility.

This post dives into the difference between the two.

Setting the stage

Here are some terms to familiarize yourself with:

Schema — Definition of the types of data and any context needed to understand it. Schemas are independent of how the data is encoded as multiple serialization options are possible (JSON, binary, etc.). Schemas can also be versioned, something which is crucial to understanding backward and forward compatibility.

Reader — The service that parses the data. In the case of a client-server application, this is the client whenever the server…

Steven Heidel

I develop software and develop people. stevenheidel.com