skip to content

questions

5

A wire schema gains a new version: what does backward compatibility guarantee about readers and data, and how does forward compatibility differ?

level: middleimportance: must knowfreq 78%

answer

  1. always ask: which side reads?
  2. a direction in time, not a rank
  3. one guarantee per version pair
  4. new code meeting older records
  5. old code meeting newer records

basics

~20 s

Backward compatibility means a reader on the new schema can decode data written under the old one. Forward compatibility is the mirror image: a reader still on the old schema can decode data written under the new one.

solid answer

~40 s

Both names describe the **reader**, and the direction in time it has to cope with. **Backward** compatible means a reader using version `N` can decode records a writer produced under version `N-1` — new code reaching backwards at older data. **Forward** compatible means a reader still on `N-1` can decode records a writer produced under `N` — old code coping with data from its future. **Full** compatibility is both directions holding for the same pair of versions. The payoff is deployment freedom: whichever direction holds tells you which side of the fleet may move first while both versions run side by side. The guarantee is always relative to a named pair of versions, never an absolute property of one schema.

go deeper

for a junior

Learn the two terms as a pair and always attach them to the reader: one describes new code meeting older records, the other old code meeting newer records. Mixing them up is the single most common slip in this material.

for a middle

Explain that the guarantee is defined over a version pair plus a direction, derive full compatibility as the conjunction of the two, and show that a change can satisfy one direction while violating the other.

for a senior

Show you have used the guarantee operationally: name the direction that holds and say which side of a fleet you may therefore upgrade first while both versions run together for days.

for a principal

Frame the guarantee as a tax levied on schema authors in exchange for removing cross-team deployment coordination, and be ready to say which channels are worth taxing at which strength.

## What the two words are actually about A **compatibility guarantee** is a statement about one decode. A **reader** running some version of a schema is handed bytes that a **writer** produced under some other version, and the guarantee says whether that decode is defined. Three things must be named before the statement means anything: the reader's version, the writer's version, and which of the two is older. Candidates who mix the two terms up almost always do so because they attach the word to the *change* or to *whoever deployed*, rather than to the reader. The convention is consistent wherever the terms are used: - **Backward compatible** — a reader on the **newer** schema can decode data written under an **older** one. The new code reaches backwards in time. - **Forward compatible** — a reader on the **older** schema can decode data written under a **newer** one. The old code has to cope with data from its future. - **Full compatible** — both of the above hold, for the same pair of versions. A useful discipline: say the sentence out loud with both versions in it. "A version 5 reader decodes version 4 data" is unambiguous even if you have forgotten which label it carries; the label is just shorthand for that sentence. ## The pair, not the schema Compatibility is a **relation over a pair**, not a property of a single artifact. "Version 5 is backward compatible" is an incomplete claim in the same way that "this number is larger" is incomplete. Version 5 may be backward compatible with version 4 and not with version 2; the two statements are independent, because each concerns a different set of bytes arriving at the same decoder. This matters in three concrete ways: 1. A claim that names no second version cannot be checked, so it cannot be relied on. 2. Two changes that are each compatible with their predecessor can compose into a pair that is not — the stronger, history-wide claim is a separate and strictly stronger guarantee. 3. A request type and a response type between the same two services are two different contracts with two different readers, so they carry their own guarantees independently. ## The table to keep in your head | Guarantee | Reader's version | Data's version | What it buys you | |---|---|---|---| | Backward | newer | older | readers may be upgraded ahead of writers | | Forward | older | newer | writers may be upgraded ahead of readers | | Full | either | either | no upgrade ordering constraint at all | Read the middle two columns first and the label falls out. If the reader is newer than the data, you are talking about backward compatibility. If the reader is older than the data, you are talking about forward compatibility. If you cannot say which is newer, the question has not been posed properly yet. ## Why an interviewer asks this The question is not vocabulary for its own sake. During any rolling change there is a window — minutes for a small service, days for a fleet of a few hundred consumers and a handful of producers — in which both versions are live simultaneously. In that window, four writer/reader pairings occur. Two of them are same-version pairings that were already working. The other two are the cross pairings, and **each direction of compatibility covers exactly one of them**. So the direction that holds is the same fact as the deployment order you are allowed to use, stated a different way. An engineer who can move fluently between "this change is backward compatible" and "therefore consumers go first" has done the rollout; one who can only recite the definitions has not. ## Where the guarantee stops These terms are narrower than they sound, and the boundaries are worth stating explicitly: - They are about **decoding**, not meaning. A field silently repurposed to carry a different quantity under the same name decodes cleanly in both directions and still corrupts everything downstream. No compatibility check catches that, because nothing about the bytes changed shape. - They cover one **version pair**, not a history. Extending the claim over every past version is the transitive form, and it does not follow from the per-step checks. - They say nothing about **which concrete edits** satisfy each direction. That is a separate catalogue, and the answer differs between families of encodings. - Ecosystems genuinely differ in how they express the rules — some resolve a reader's schema against the writer's at decode time, others match on field identifiers alone — but the direction being named is the same in all of them, which is why the terms travel. ## The habit that prevents the mix-up When the label slips, rebuild it from scratch in three steps: name the reader's version; name the version the bytes were written under; ask which is older. Reader newer than the data means backward. Reader older than the data means forward. Both required at once means full, and full is the claim you make when nothing lets you control which side moves first.

  • Is compatibility a property of a schema on its own?
    No. It is a property of a **pair** — the reader's version and the version the data was written under — together with a direction. One schema can be backward compatible with the version immediately before it and incompatible with one three releases back, so a compatibility claim that does not name both versions is not yet a claim you can check.
  • What does full compatibility buy that a single direction does not?
    It removes deployment ordering entirely. Readers and writers on either version can be mixed in any proportion and any sequence, which is what you need when you cannot control the order: many independent consumer teams, data that outlives the release, or a request and response pair where both sides move on their own schedule.
  • Where does a compatibility guarantee stop protecting you?
    At the boundary of decoding. The guarantee says a reader can parse the bytes and populate its own model; it says nothing about whether the meaning survived. A field quietly repurposed to carry a different quantity under the same name satisfies both directions and still produces wrong numbers in every consumer that reads it.

A clerk trained on this year's form who can still process last year's submissions is reading backwards in time, while a clerk still trained on last year's form who is handed this year's submissions must cope with its future. The label always names which way the reader is looking, never which version of the form is better.

saying these in an interview costs you the question

  • Thinks backward compatibility means old code reading new data
  • Calls a schema compatible without naming which two versions
  • Believes forward compatibility is just backward compatibility restated
  • Assumes any change that still decodes has preserved the meaning
  • Treats full compatibility as a free default rather than a cost
open as a page

Several hundred consumers and a handful of producers must move to a new schema over days: which side upgrades first?

level: seniorimportance: must knowfreq 65%

basics

~20 s

The direction that holds decides the order. A backward-compatible change lets the readers go first, since new readers cope with data still written under the old schema; a forward-compatible change lets the writers go first. Full compatibility means any order works.

open as a page

Two services exchange a request and a response and each deploys on its own schedule: why is one compatibility direction not enough?

level: seniorimportance: should knowfreq 52%

basics

~20 s

Each side writes on one hop and reads on the other, so a single deployment imposes opposite requirements at once: an old callee must read new requests while a new caller must read old responses. Only both directions cover both hops.

open as a page

Which compatibility guarantee would you require for a long-retention event stream versus a short-lived internal channel, and why?

level: principalimportance: should knowfreq 38%

basics

~20 s

Match the guarantee to how long data and stragglers outlive a release. A long-retention stream needs a transitive guarantee so current readers can replay all of history; a short-lived channel drained between releases can run honestly on the weaker per-step form.

open as a page

What does the transitive form of a compatibility guarantee quantify over that the plain form does not?

level: seniorimportance: nice to knowfreq 30%

basics

~20 s

Transitive compatibility quantifies over every earlier version, not just the immediately preceding one. Plain per-step checks do not compose: version 3 can pass against version 2, and version 2 against version 1, while a version 3 reader still fails on version 1 data.

open as a page