Prompt and context
This migration changes both a field name and its meaning: total_cents assumes USD, while amount_minor must work with an explicit currency. An Avro alias can aid name resolution, but it cannot prove that “cents” was correctly migrated to “minor currency units.”
What the interviewer evaluates
- Expanding readers before producers populate the new field.
- Separating structural compatibility from amount semantics.
- Preserving old schemas and transformations for 90-day replay.
- Retiring from consumer evidence rather than a calendar date.
Clarifications before answering
Confirm format, registry mode, unknown-field behavior, amount representation, currency availability, slowest consumer, and replay cycle. Ask whether a v2 topic is available when both meanings cannot be represented compatibly.
A 30-second answer framework
Add optional amount_minor and currency first. Upgrade every consumer to prefer the new fields and fall back to total_cents, validating equality for USD events. Then dual-populate producers and stop new business logic from reading the old field. Preserve historical schemas and transforms beyond 90 days. Remove the old field only after producers stop writing it, consumers and offline dependencies stop reading it, and a complete 90-day replay passes with the new schema.
Step-by-step deep dive
Phase one is additive. Registry compatibility and a CI reader/writer matrix block invalid versions. Consumers gain dual-read support before new producers deploy.
Phase two dual-populates. USD requires amount_minor == total_cents and currency == USD; non-USD events populate only the truthful new semantics. Track coverage, fallback, and mismatches by producer version, consumer, and currency.
Phase three stops business dependence on the old field while preserving replay. The replayer chooses transforms by writer schema ID rather than interpreting history with today's defaults. If one subject cannot express both meanings safely, use a v2 topic and explicit translator.
Retire only after all producers stop old writes, fallback reaches zero, the full replay window passes, and offline jobs are inventoried. Keep a deployable rollback schema and transform version.
Strong sample answer
I would use expand-migrate-contract: add fields and upgrade readers, dual-write and reconcile, then retire the old field only when the evidence shows every dependency has left it. Aliases solve naming only; currency semantics need contract tests and runtime invariants.
The old field remains through one full replay window. If USD dual writes disagree, freeze the rollout and keep total_cents authoritative for that USD batch while the producer is repaired. Non-USD events must keep amount_minor + currency authoritative; pause new non-USD ingestion or route it to a v2 topic rather than inventing a cents value. After retirement, both new fields become required runtime invariants. Contract removal begins only after online, offline, and replay paths have closed.
Common mistakes
- Renaming the field in one schema commit.
- Treating an alias as an amount conversion.
- Deploying producers before consumers.
- Reading old history with today's default currency.
- Missing offline and replay consumers.
Follow-up questions
Why is an alias insufficient?
It helps resolve a field name; it does not prove that cents and another currency's minor unit have equivalent meaning.
When is a v2 topic required?
When old and new meanings cannot be represented unambiguously under the required compatibility contract.
What if dual writes disagree?
For USD dual writes, stop rollout, keep total_cents authoritative for the affected batch, isolate by producer version, fix, and replay. For non-USD, keep amount_minor + currency authoritative and pause ingestion or use a v2 topic; never fall back to a fabricated cents value.
When can the old field be deleted?
After old writes stop, fallback is zero, the complete replay window passes, and the offline inventory is clear.