Learn Labs
5. Encoding and Evolution

5.10 Decision cheat sheet

Ask both directions separately. Can new code read old data? (backward) Can old code read new data? (forward) A change is only safe if the answer to both is yes for the duration of…

Decision cheat sheet
0 rows

Which encoding?

SituationChoose
Public API, cross-organization, must be debuggableJSON + OpenAPI
Internal service-to-service, high volume, typed languagesProtobuf + gRPC
Streaming/analytics, many records per file, schemas generated from dataAvro + schema registry
Columnar analytics filesParquet
Anything at allNever a language-native format

Is this change safe? Ask both directions separately. Can new code read old data? (backward) Can old code read new data? (forward) A change is only safe if the answer to both is yes for the duration of your rolling upgrade window — which, for public APIs, may be indefinite.

Protobuf or Avro? Protobuf when the reader shouldn't need the writer's schema (RPC, self-contained messages) and schemas are hand-authored. Avro when schemas are dynamically generated or there's one schema per file/topic, and you're willing to run a registry.

RPC or messaging? RPC when the caller needs the answer now and the callee's availability is acceptable. Messaging when you want buffering, redelivery, fan-out, and decoupling — and can tolerate asynchrony.

How do I version a public API? Pick one mechanism (URL path is the least surprising), instrument usage per version and per client from day one, publish a deprecation policy, and expect to run old versions far longer than you planned.

Do I need durable execution? Only when a multi-step process spans services or third parties and partial completion is unacceptable. Otherwise a retry with an idempotency key is simpler and less brittle. If you adopt it, commit to determinism and to versioning-by-deployment.