Iceberg vs Delta Lake vs Hudi

How to Choose (2026)

Choose Delta Lake when your platform is Databricks or Spark, and Apache Iceberg when several engines must read and write the same tables. Hudi is the third option, built for frequent record-level upserts. All 3 put ACID commits on Parquet files, and they differ in how they lay out metadata and store deletes, and in which engines support them natively.

Last updated: Proudly published by: Jeff Wahl11 min read

Iceberg vs Delta Lake: the short answer

Choose Delta Lake when your platform is Databricks or Spark and you want the tightest integration, and choose Apache Iceberg when several engines must read and write the same tables. Hudi is the third option, built for frequent record-level upserts and deletes on incremental pipelines.

All 3 formats do the same core job. They keep data in Parquet files on object storage and add a metadata layer that gives a table atomic commits and snapshots, and supports schema evolution along with row-level changes. They differ in how that metadata is laid out, how a commit is made atomic, how deletes are stored and how many engines and services support them natively. Those differences, not the headline feature lists, decide which one fits.

A caution on any comparison written from memory, including old ones: both projects ship quickly. Iceberg's format version 3 added deletion vectors and row lineage, and Delta Lake 4.x added catalog-managed tables, so a post from 2022 describes a different pair of formats.

Iceberg vs Delta Lake vs Hudi at a glance

Iceberg
  • Table state kept inMetadata file tree
  • Commit is atomic byCatalog pointer swap
  • Row deletesDelete files, v3 vectors
  • Layout tuningHidden partitioning
  • Update strategyCopy or merge on read
  • Best fitMany engines
Delta Lake
  • Table state kept inOrdered JSON log
  • Commit is atomic byNew numbered log file
  • Row deletesDeletion vectors
  • Layout tuningLiquid clustering
  • Update strategyCopy or vectors
  • Best fitSpark, Databricks
Hudi
  • Table state kept inTimeline of instants
  • Commit is atomic byTimeline instant file
  • Row deletesLog files, compaction
  • Layout tuningIndexes, clustering
  • Update strategyCopy or merge on read
  • Best fitFrequent upserts

How Iceberg and Delta Lake track a table's files

Both formats answer the same question: which Parquet files make up the table right now? Iceberg answers it with a tree. A catalog holds a pointer to the current table metadata file. That file records the schema and partition spec, plus the snapshots, and each snapshot names a manifest list. The manifest list names manifests, and each manifest has a row per data file with its partition values and column statistics. A reader walks the pointer down to the files, and can skip whole manifests whose statistics rule them out.

Delta Lake answers it with a log. Each commit is a JSON file in the table's _delta_log folder, named with the next version number zero padded to 20 digits, such as 00000000000000000008.json. The file lists actions: files added, files removed, metadata changes. Replaying the log from the start reconstructs the table, so Delta writes Parquet checkpoints that summarize the log up to a version, and a _last_checkpoint file points a reader at a recent one. The Delta protocol states that delta files are the unit of atomicity for a table.

2 lanes. Iceberg: a catalog pointer leads to the metadata file v8.metadata.json, then a manifest list, a manifest and the data files. Delta Lake: a _delta_log folder holds commit files …0007.json and the new …0008.json, which point at the same data files2 lanes. Iceberg: a catalog pointer leads to the metadata file v8.metadata.json, then a manifest list, a manifest and the data files. Delta Lake: a _delta_log folder holds commit files …0007.json and the new …0008.json, which point at the same data files

The practical difference shows up in planning. Iceberg reads the metadata file and the manifests it needs, and can skip manifests that cover no matching files. Delta reads the latest checkpoint plus the JSON commits after it. Both need housekeeping when the metadata grows.

Prepare for the interview
01 / Open invite
02min.

Know Iceberg vs Delta Lake the way the interviewer who asks it knows it.

a Iceberg vs Delta Lake query, the same shape a screen would give you.
The diff against expected. Where ties broke. What you missed.
sandbox
1SELECT user_id,
2 COUNT(*) AS sessions
3FROM events
4WHERE ts >= NOW() - INTERVAL '7 day'
5
Execute your solution0.4s avg.
PinterestInterview question
Solve a Iceberg vs Delta Lake problem

How do concurrent writers work in Iceberg and Delta Lake?

Both formats use optimistic concurrency. A writer reads the table, writes its new data files without taking a lock, and only at commit time checks whether anyone else got there first. Writers never block each other while they work, and a conflict costs a retry or a failed job rather than a corrupted table.

Take 2 writers that both read the table at version 7. Each prepares an append. Writer A commits first. In Delta, A creates 00000000000000000008.json. In Iceberg, A swaps the catalog's pointer from the version 7 metadata file to its new one. Writer B now tries the same step from a stale base. In Delta, creating version 8 fails because it exists; in Iceberg, the swap fails because the pointer no longer holds the value B expected.

B doesn't simply fail. It checks what A changed. The Iceberg spec says the writer "must retry the update based on the new current version", and some operations can be re-applied when well-defined conditions hold. 2 appends commute, so B re-applies on top of A and lands at version 9. Delta does the same check against the files and partitions B read: an operation that read a file A deleted fails with ConcurrentDeleteReadException, one that read a partition A appended to can fail with ConcurrentAppendException, and 2 plain inserts cannot conflict.

Where the 2 diverge is what makes the commit atomic. Iceberg needs an atomic compare-and-swap, which the catalog provides, so the catalog is part of the correctness story and not only a name lookup. A Delta commit on plain object storage needs the store to create a log file only if it is absent, and catalog-managed Delta tables move that ratification into a catalog as well. If an interviewer asks what makes a lakehouse commit atomic, the answer is that data files are immutable and one small metadata step either happens or does not.

Isolation is the other axis. Delta documents 2 levels, with WriteSerializable as the default on Databricks and Serializable available per table, and with row-level conflict detection when deletion vectors are on, so 2 writers touching different rows of one file need not conflict. Iceberg's spec bases serializable isolation on the metadata swap, and its engines decide how finely they detect conflicts. Partitioning your writes so concurrent jobs touch different partitions reduces conflicts in both.

Partitioning: hidden partitioning vs liquid clustering

Iceberg treats partitioning as table configuration, not as extra columns. Declaring day(ts) or bucket(16, id) on a source column is enough, and Iceberg derives the partition value itself. Because readers filter on the real column, a query on ts prunes partitions without anyone writing a ts_day predicate. The spec lists 8 transforms: identity, bucket, truncate, void, and the time ones year, month, day and hour.

The larger benefit is evolution. Changing a table's partition spec is a metadata operation that does not rewrite files, so old data keeps the old layout and new data uses the new one. A table partitioned by month while it was small can move to day as it grows, and a query plans each layout with its own derived filter.

Delta Lake partitions by explicit columns and offers liquid clustering as the alternative. You declare CLUSTER BY with up to 4 columns, and OPTIMIZE clusters data incrementally. Changing the keys does not rewrite existing data, which gives Delta the same cheap-to-change property by a different route. A clustered table can't also use partitioning or ZORDER, so the choice is per table.

The decision rule: low-cardinality, time-shaped access favours Iceberg's transforms, which are portable across engines, while multi-column filter patterns that change over time suit Delta's clustering. In either, avoid partitions so fine that each holds a few small files, because small files cost more in metadata and listing than pruning saves.

Declaring layout in Iceberg and in Delta Lake

SQLiceberg.sql
CREATE TABLE prod.db.events (
    id bigint,
    category string,
    ts timestamp)
USING iceberg
PARTITIONED BY (bucket(16, id), day(ts));

-- Evolve the spec: a metadata change, old files keep their layout
ALTER TABLE prod.db.events ADD PARTITION FIELD category;

How do row-level deletes and updates work?

Parquet files are immutable, so deleting 1 row means one of 2 things: write a new file without it, or write a note saying the row is gone. The first is copy-on-write, the second merge-on-read.

The cost gap is easy to see. Say a 128 MB file holds 1,000,000 rows and a job deletes 1 of them. Copy-on-write rewrites the file, which writes 128 MB and 999,999 rows to remove 1. A merge-on-read delete records 1 deleted position, and the file stays as it is. The price moves to the reader, which must apply that record, and to maintenance, which eventually folds the deletes in.

Iceberg v2 introduced delete files for this. A position delete file names a data file and the row position in it; an equality delete file identifies rows by column values, which suits streaming upserts where the writer does not know the file. Sequence numbers decide which delete files apply to which data file. Delta Lake commits remove and add whole files, or mark rows through deletion vectors.

Both formats let you choose per table. Copy-on-write keeps reads fast and suits tables that are read far more than they're changed. Merge-on-read keeps writes fast and suits frequent small changes such as CDC, at the cost of read-time merging until compaction runs.

Iceberg deletion vectors vs Delta deletion vectors

A deletion vector stores the deleted row positions of one data file as a compressed Roaring bitmap. Delta Lake has them behind the deletionVectors table feature, which needs reader version 3 and writer version 7. The property delta.enableDeletionVectors turns them on, and enabling it upgrades the table protocol, so older Delta clients can no longer read the table.

Iceberg added the same idea in format version 3. A deletion vector is a deletion-vector-v1 blob in a Puffin file, built on 32-bit Roaring bitmaps, and a snapshot may hold at most 1 per data file. The Iceberg spec also says position delete files must not be added to v3 tables, though existing ones stay valid, so on v3 the vector replaces the position delete file for new work.

In both, soft deleted rows stay in the data file until a rewrite. In Delta, OPTIMIZE rewrites the files, as does REORG TABLE ... APPLY (PURGE), and old files linger until VACUUM. In Iceberg, compaction rewrites data files and expiring snapshots lets old files go. The vector shrinks the cost of the delete itself, not the cost of the cleanup.

Check support before you commit to the feature. A v3 table needs engines and catalogs that implement v3, and a Delta table with deletion vectors is not translated by every interoperability tool.

Can Iceberg and Delta Lake interoperate?

Not natively, but the data files are the same Parquet either way, so what must be translated is the metadata. 2 tools do that. Delta UniForm generates Iceberg metadata after each Delta commit, so one copy of the Parquet files serves both. Iceberg and Hudi clients then read the table and can't write to it, and the documentation warns that an outside writer can destroy the Delta table.

Apache XTable is the format-neutral route. It is not a new format. It reads a table's metadata and writes metadata for another format into the same base path, among those 3 formats. It's an incubating Apache project, and its documented limits include Delta deletion vectors and merge-on-read tables, so check which features your table uses against its supported list.

The pattern most teams settle on is to write in one format and expose the table to other engines through a catalog, not to dual-write. Pick the writer format by who writes the table, and treat the other formats as read paths. Also look at the catalog: it decides discovery and access control, and for Iceberg and catalog-managed Delta it also decides commit atomicity.

Where does Apache Hudi fit?

Hudi brings database-style upserts and deletes to data lakes and keeps a timeline of every action on a table under .hoodie. Each action moves from requested to inflight to completed, and the current state is the highest state recorded. That timeline plays the role of Iceberg's metadata tree and Delta's log.

Its distinguishing feature is indexing. To upsert a record, the writer must find which file holds that record. Hudi's indexes exist to make that lookup cheap: a record index that maps a record key to its location, plus bloom filter and bucket indexes, and secondary and expression indexes. Without one, finding the files to rewrite means scanning the dataset.

Hudi's 2 table types map to the delete trade-off above. Copy-on-write rewrites base files on every update. Merge-on-read appends changes to row-based log files and a periodic compaction folds them into new base files, which lowers write latency and raises query latency until compaction runs.

In Hudi vs Iceberg vs Delta comparisons, Hudi wins when the workload is high-frequency upserts or CDC ingestion into a lake and you want the index as a first-class part of the table. It loses on engine support: Iceberg and Delta are the formats most engines and managed services target. Delta UniForm lists Hudi output as a preview, so treat Hudi readers of a Delta table as experimental.

What maintenance does each format need?

A table format moves cost from write time to maintenance, and every format needs a schedule for it. Small files come from frequent commits and slow every read, so each has a compaction path. Delta uses OPTIMIZE and Iceberg has a compact data files action, while Hudi runs compaction and clustering services.

Old snapshots are the second job. Time travel keeps old data files and metadata alive, so Iceberg's recommended maintenance is to expire snapshots, remove old metadata files and delete orphan files, and Delta's is VACUUM. Delete too eagerly and you lose time travel and break long-running readers. Delete too late and storage grows with every rewrite.

Plan this before launch. A common production failure is a table whose metadata grew without bound because nobody scheduled the cleanup, and it is a fair system design question about any lakehouse pipeline.

How to choose between Iceberg, Delta Lake and Hudi

Start with where the table is written and read, because engine support outweighs any single feature. If your jobs run on Databricks or Spark and the table mostly lives there, Delta Lake is the lowest-friction choice. If the table must be shared by Flink and Trino, or by Snowflake alongside other engines, Iceberg's engine-neutral spec and catalog model fit better.

Then look at the write pattern. Append-heavy tables with occasional corrections suit either format. A table that receives a steady stream of row updates from CDC deserves a closer look at Hudi, or at merge-on-read with deletion vectors on Iceberg v3 or Delta, and a test of read latency before compaction.

Last, price the exit. Because all 3 store Parquet, switching is a metadata problem and tools exist for it, so no choice is permanent. That makes the right move to choose for the next 2 years of your platform and avoid anything built around a single feature that has no equivalent elsewhere.

How table formats come up in data engineering interviews

Interviewers rarely ask you to recite feature lists. They ask what problem a table format solves, why it makes object storage transactional, and how you would handle a late-arriving correction or a GDPR delete on a petabyte table. The answers above carry most of it: immutable files, a metadata step that is atomic, and a choice between rewriting files and recording deletes.

Expect follow-ups on the failure modes: what happens when 2 jobs write at once, why small files hurt, and what you would schedule to keep the table healthy. The data engineer interview prep path covers those topics. For Spark reads and writes on these tables, use the PySpark interview questions and the PySpark practice problems.

If your target team runs on Databricks, Databricks interview questions cover OPTIMIZE and VACUUM on Delta, and clustering as well.

Iceberg vs Delta Lake FAQ

What is the difference between Iceberg and Delta Lake?+
Both put ACID transactions on Parquet files in object storage. Iceberg tracks a table through a tree of metadata files and commits by swapping one pointer in a catalog. Delta Lake tracks it through an ordered log of JSON commits in a `_delta_log` folder. In practice Iceberg is the more engine-neutral format and Delta is the tightest fit with Spark and Databricks.
Is Delta Lake or Iceberg better?+
Neither wins on every axis. Pick Delta Lake when your platform is Databricks or Spark centred, and Iceberg when engines such as Spark and Flink, or Trino and Snowflake, must read and write the same tables. A UniForm-enabled Delta table narrows the gap for read-only Iceberg clients.
What does Hudi do that Iceberg and Delta Lake do not?+
Hudi was built for record-level upserts and deletes on incremental pipelines. It indexes record keys, including a record index that maps a key to its file location, and offers merge-on-read tables that append changes to log files and compact them later.
Can Iceberg and Delta Lake read each other's tables?+
Not natively. Delta UniForm writes Iceberg metadata beside a Delta table so Iceberg clients can read it, and Apache XTable translates metadata between the 3 formats. Both leave the Parquet data files in place, and the foreign format is read-only.
Do Iceberg and Delta Lake both support deletion vectors?+
Yes. Delta Lake supports them through the `deletionVectors` table feature, and Iceberg added binary deletion vectors in format version 3. Both record deleted row positions in a Roaring bitmap instead of rewriting the data file.
Which table format is easiest to migrate away from?+
All 3 store data as Parquet files, so the data itself is portable. What you rebuild is the metadata, which tools such as UniForm and Apache XTable can generate. Features with no equivalent, such as deletion vectors on some paths, are where translation stops.
Do table formats replace a data warehouse?+
They replace the storage layer, not the engine. A table format gives files in object storage transactions and snapshots, and lets the schema evolve, but you still need an engine to run queries. Together they form the lakehouse pattern.
02 / Why practice

The candidate who gets the offer

  1. 01

    Reading a solution is not the same as writing one

    Every engineer who has frozen on a query they had read a dozen times knows the gap. The only preparation that closes it is producing the answer yourself, under time, before the interview does it for you

  2. 02

    76% of hiring managers reject on the coding task, not the resume

    From HackerRank's 2024 Developer Skills Report. Candidates who look strong on paper still fail the live screen if they haven't done timed, executable practice

  3. 03

    Spark rounds are diagnosis rounds

    Skew, shuffles, broadcast judgment, partition pruning, exactly-once streaming. Reading the task table and naming the failure class is the signal, not the API

Related guides