pattern

Copy-on-Write vs Merge-on-Read

also called CoW vs MoR, Table Write Mode

The choice between rewriting whole data files on every update (cheap reads, costly writes) and logging changes beside them to merge later (cheap writes, costlier reads).

apache hudiicebergdeltaupsertswrite amplificationcompaction

A lake table receives 8 million row updates an hour, and every commit rewrites 77 GB of Parquet to land 1.6 GB of change. The dashboards are fast and the storage bill and commit latency are not. The cause is the table's write mode: copy-on-write rewrites each data file that contains a changed row, while merge-on-read leaves base files alone and writes the change to a small delta or deletion file, merging it at read time or during background compaction.

The choice moves cost between the write path and the read path. Neither is better in general; it is a decision about which side of the table your workload can afford to slow down.

Why it matters

Write amplification is the ratio of bytes written to bytes logically changed. With copy-on-write it is roughly the file size divided by the changed bytes per file, which is enormous when small updates are scattered across many files. Merge-on-read brings it near 1, at the price of a read that must combine a base file with its deltas. The wrong mode shows up as commit times that grow with table size (copy-on-write on a spread-out update pattern) or as query latency that creeps up between compactions (merge-on-read with lagging compaction).

Implementation patterns

  • Copy-on-write: update locality decides cost. Cluster the table by the update key (for example, the entity id) so changed rows land in few files.
  • Merge-on-read: base files plus delta logs (Hudi log files, Iceberg position or equality deletes, Delta deletion vectors). A compaction job folds deltas into new base files on a schedule driven by delta count or age.
  • Hybrid: merge-on-read for the hot, recent partitions and copy-on-write (or compaction-forced rewrite) for cold ones, so history is stored in the simple layout.
  • Mode per table, not per platform: a slowly changing dimension and an event-state table usually want different modes.

Industry example

Apache Hudi was created at Uber, which described the work publicly in 2017: trip and rider state changed after the fact, and rewriting entire Hive partitions to apply updates made data arrive a day late. Hudi's two table types, copy-on-write and merge-on-read, expose exactly this trade-off, and the other open table formats offer comparable mechanisms for row-level deletes.

Failure scenarios

  • Compaction falls behind after a traffic spike; delta files per file group climb from 3 to 80 and dashboard queries slow 5x with no change in data volume. Signal: delta count per file group.
  • An engine that cannot read deltas silently returns stale base-file data for a merge-on-read table, so one consumer disagrees with the others. Signal: row-count mismatch between engines.
  • Copy-on-write on a wide update spread rewrites the full window every hour and misses its commit interval, so the pipeline's freshness degrades gradually.

Trade-offs

Choose Gains Pays
Copy-on-write Simple files, fast reads, any engine High write amplification, slow commits under scattered updates
Merge-on-read Cheap commits, low latency to land changes Read-time merge, a compaction service to run, engine compatibility checks

When not to use it

For append-only tables there is nothing to choose: both modes behave the same. For a table updated once a day in bulk, copy-on-write or a partition overwrite is simpler. Do not adopt merge-on-read for a handful of GB because someone has read about it.

Interview question

Q: You own a lake table receiving frequent scattered updates and a dashboard SLA of 5 seconds. How do you choose the write mode?

What a strong answer covers: estimating write amplification from update spread and file size; picking merge-on-read when scattered updates dominate; naming the compaction lag metric and its alert; checking every consumer engine can read the merged view; the hybrid option for hot versus cold partitions; and the flip to copy-on-write when updates are rare or clustered.

Quick check

Quiz: Updates touch about 0.1% of files per day and readers use three different engines. Which mode? Copy-on-write: rewrites are cheap and every engine reads plain files.

Flashcard: What does merge-on-read trade away? — Read speed and simplicity, in return for cheap writes; compaction lag shows up as slow queries.