NoSQL · Data models beyond tables
How do you evolve a schema in a NoSQL database?
Short answer
Use expand-migrate-contract: add the new shape alongside the old, backfill and dual-write, switch reads, then remove the old shape. Version documents and keep the migration resumable and observable.
NoSQL databases often let you write a new field without a migration, but that does not make schema changes free. Readers must handle both shapes, and existing data still needs to be transformed. The safe pattern separates deployment from backfill.
Expand, migrate, contract
- Expand: deploy code that writes both old and new fields and reads either
- Backfill: transform existing records in batches, with checkpoints and rate limits
- Migrate: switch reads to the new field and verify results
- Contract: stop writing the old field and remove it after a safety window
function migrateAddress(doc) {
if (doc.schemaVersion >= 2) return null;
const address = doc.addressLine
? { line1: doc.addressLine, city: doc.city }
: { line1: null, city: null };
return {
updateOne: {
filter: { _id: doc._id, schemaVersion: { $lt: 2 } },
update: {
$set: { address, schemaVersion: 2 },
$unset: { addressLine: "", city: "" }
}
}
};
}Backfills compete with live traffic for I/O and capacity. Run them in bounded batches, pause on error-rate or latency thresholds, and make them resumable. For large collections, a background job that records its last processed key is safer than one long pass.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Why is a schema migration harder without a fixed schema?
- 2How do you make a backfill resumable?
- 3When is it safe to remove the old field?
- 4How do you roll back a failed migration?
Say it in the interview
Even though NoSQL lets me add fields without a formal migration, readers still have to handle old and new shapes. I use expand, migrate, contract: first write both shapes and read either, then backfill in bounded, resumable batches, switch reads, and only later remove the old field. I version documents so the job is idempotent. I keep dual writes and a rollback path until the new shape is proven, and I watch latency and error rates while the backfill competes with live traffic.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live NoSQL mock interview and get scored feedback on depth, clarity and confidence.