Optional or default
New fields ship as optional or with a default value.
Chapter 04 · Encoding & Evolution
You deployed a new field. Half your servers are old. Nothing broke. Why?
Two versions of your code are alive at once, reading each other's data.
Three acts: 1. wire 2. directions 3. rules
Same record. Same three fields. Three encodings.
Rolling deploy: old and new code trade rows at the same time.
both directions must hold, at the same moment
Takeaway
Old code writing to new. New code reading old. Both directions must hold, at the same moment.
New fields ship as optional or with a default value.
Field tags (Protobuf) or names (Avro) never get reused. Retire them; don't recycle.
Unknown fields are preserved or ignored, never rejected.
Follow all three and the fleet can be any mix of versions at any moment.
── Reference ──
Six formats · one evolution matrix · four things to remember.
| Format | Bytes* | Schema | Evolution | Human-readable | Tags on wire | Notable users |
|---|---|---|---|---|---|---|
| JSON | 81 | none | tolerant readers | yes | field names | web APIs everywhere |
| XML | ~150 | XSD (optional) | tolerant readers | yes | tag names | legacy enterprise, SOAP |
| MessagePack | 66 | none | tolerant readers | no | field names | Fluentd, polyglot msgpack libraries |
| Thrift | 59 | .thrift IDL | tag numbers stable | no | field tags | Facebook, Cassandra RPC |
| Protobuf | 33 | .proto IDL | tag numbers stable | no | field tags | Google, gRPC, Kubernetes |
| Avro | 32 | .avsc | writer/reader schema resolution | no | none (schema ships) | Kafka, Hadoop, Confluent |
* Bytes for the sample record used in DDIA §4.1 Figures 4-1 through 4-6.
| Operation | JSON / XML | Protobuf / Thrift | Avro |
|---|---|---|---|
| Add optional field | safe | safe (with default) | safe (with default in reader) |
| Remove optional field | safe | safe (leave tag number reserved) | safe (with default in reader) |
| Add required field | breaks forward compat | breaks forward compat | writers must upgrade first |
| Change field type | dangerous | limited (varint-compatible only) | limited (per Avro resolution rules) |
| Rename field | breaks | tag stays; symbol can change | field aliases supported |
JSON / XML → schemaless, verbose, universal; tolerant readers do the compatibility work.
Protobuf / Thrift → schema with tag numbers; tags on wire enable evolution.
Avro → schema per file; writer's schema ships; no tags on wire.
Backward vs forward → new code reading old data vs old code reading new data; both must hold during rolling deploy.