CASE STUDY

Evaluating and Executing a MySQL to MongoDB Migration

4 min read·608 words·Intermediate

Asked at

1 candidate report in Aug 2026

How to use this case study

SDE-2 / Mid

Compare relational (tables, joins, transactions) and document (nested JSON documents) models, and say when each fits.

SDE-3 / Senior

Decide based on access patterns and consistency needs, then plan a safe migration: dual writes or CDC, backfill, validation, shadow reads and cutover with rollback.

Staff / Principal

Demand evidence for the claimed benefits (benchmarks, metrics), consider cheaper alternatives (indexes, sharding MySQL), and manage risk and team skills.


0) Problem Restatement

TikTok asked: a team proposes migrating an existing MySQL-backed service to MongoDB. How would you:

  1. decide whether the migration is justified,
  2. compare the data models and consistency needs,
  3. execute the migration safely, and
  4. prove the claimed benefits?


1) Step 1: Understand the Motivation

Ask "what problem are we solving?". Common reasons:

  • "Schema changes are painful" (the data is naturally nested or varies per record).
  • "We need to scale writes beyond one MySQL primary."
  • "Our queries always load a whole object with 5 joins."
Then ask whether there are cheaper fixes: better indexes, query tuning, read replicas, caching, JSON columns in MySQL, or sharding MySQL (Vitess). A migration is costly and risky, so it must clearly beat these.


2) Step 2: Compare Models Against Real Access Patterns

AspectMySQL (relational)MongoDB (document)
Data shapeNormalized tables, joinsNested documents (an object and its children together)
TransactionsMature multi-row ACIDMulti-document transactions exist, but best to design single-document updates
SchemaEnforced, migrations neededFlexible (validation optional)
Scaling writesVertical, or manual/Vitess shardingBuilt-in sharding by shard key
QueriesRich joins, ad-hoc SQL, reportingGreat for "get this whole object", weaker for cross-entity joins/analytics
Good fit for MongoDB: each request reads or writes one aggregate (e.g., a user profile with settings and preferences, or a product with variable attributes), rarely joins across aggregates, and needs horizontal scaling. Bad fit: heavy relational queries across entities, strict multi-entity transactions (money, inventory), and lots of reporting SQL.

List the top 10 queries by volume and latency, and model them as documents. If most become single-document reads, that's a good sign. If many need $lookup (joins), it's a warning.


3) Step 3: Execute Safely

Architecture Diagram

flowchart LR
    APP["Service"] -->|"writes"| MY[("MySQL - source of truth")]
    MY -->|"CDC (binlog)"| SYNC["Sync pipeline - transform to documents"]
    SYNC --> MG[("MongoDB")]
    BF["Backfill job"] --> MG
    APP -->|"shadow reads - compare"| MG
    CMP["Diff checker"] --> MY
    CMP --> MG
  1. Design documents and shard key from the access patterns (a high-cardinality key that spreads writes, e.g., user_id).
  2. Backfill historical data (a snapshot export → transform → load), then keep Mongo in sync with CDC from the MySQL binlog (e.g., Debezium → Kafka → a transformer). This avoids fragile dual writes in the app.
  3. Validate: row and document counts, checksums per entity, and a continuous diff checker on samples.
  4. Shadow reads: the service reads from both, returns MySQL results, and compares them with Mongo, logging mismatches and latency.
  5. Cutover gradually: move reads to Mongo for 1% → 10% → 100% of traffic. Then switch writes (a short write freeze or dual writes during the switch), and keep reverse sync (Mongo → MySQL) for a while as a rollback path.
  6. Decommission MySQL only after a stable period.


4) Step 4: Prove the Benefits

  • Before starting: record baselines (p50/p99 latency of key queries, throughput limits, cost, developer time spent on schema changes, incidents).
  • During shadow reads: compare latency and resource use under real traffic.
  • After: the same metrics, plus cost. If the benefits don't show up, stop at the shadow phase. That's the value of a reversible plan.


5) Wrap-Up

Start from the concrete problem and rule out cheaper fixes, then compare the relational and document models against the service's real top queries and consistency needs (MongoDB fits aggregate-centric, horizontally scaling workloads, while relational fits joins, reporting and multi-entity transactions). If it's justified, migrate with a backfill plus CDC sync, validation, shadow reads, a gradual read-then-write cutover with a reverse-sync rollback path, and prove the gains against recorded baselines.

More Case Studies

Practice with a Mock Interview

Apply what you learned in a live system design mock interview with our AI interviewer.

Start System Design Interview →