Schema-evolution compatibility matrix
Add, rename, cardinality: who survives?
B = new reader reads old data · F = old reader reads new data · binary path unless noted
Protobuf (tags)
Avro (names)
add optional field
fresh tag / default
B yes · F yes
skip + preserve / default
B yes · F yes
default fills / ignore extra
rename field
same tag / alias
B yes · F yes
names absent on wire
B yes · F no
alias reads old, not new
one to many
new field + dual write
risky in place
type + packing dependent
not compatible
resolution has no such rule
parseable is not lossless: migrate cardinality via a NEW field, never by retyping