Iceberg is the champion of engine-neutral table formats. Hudi is the veteran winner for high-scale, low-latency upserts and incremental processing.
I've built production lakehouses on both Iceberg and Hudi, and the choice between them matters more than people realize. Picking the wrong table format is the kind of decision you discover is wrong 12 months in, when you're trying to add a third query engine and nothing plays nicely with your choice. Both are Apache-governed, open, mature table formats — but they were built to solve different problems, and that origin story still shapes where they shine.
Apache Iceberg came out of Netflix. The engineers there were drowning in Hive-table pain at petabyte scale — slow LIST operations on S3, no real snapshot isolation, brittle schema evolution, partition-layout decisions that couldn't be undone. Iceberg's original design goal was "make tables on object storage behave like proper database tables." Snapshot isolation, hidden partitioning, full schema evolution (including column renames and reorders), time travel as a first-class feature, and — importantly — engine neutrality. No single engine owns Iceberg. Spark, Trino, Flink, Snowflake, BigQuery, Athena, DuckDB, and ClickHouse can all read it. That neutrality is why it's won the adoption war in the last three years.
Apache Hudi came out of Uber, and the original problem was completely different: ingesting a firehose of CDC updates from operational databases into a data lake at sub-minute latency. Hive couldn't do it. Early Iceberg wasn't optimized for it. So Hudi invented two table types — Copy on Write (CoW) and Merge on Read (MoR) — to trade write amplification for query latency differently depending on your workload. Hudi also ships with a streaming ingestion tool (DeltaStreamer), built-in compaction, clustering, and cleaning services, and support for incremental queries that only return rows changed since a given commit. If your problem is "keep a lake fresh with a million upserts an hour," Hudi was designed for you.
When I help teams pick, the decision comes down to four questions:
I worked with a digital-media company that picked Hudi in 2021 because their streaming ingestion pipeline from Kafka needed upserts with sub-minute freshness. It worked great for that. Two years later they acquired a company that used Snowflake, and leadership wanted to unify analytics on Snowflake. Reading Hudi from Snowflake was possible but clunky — they ended up maintaining a sync process that re-wrote hot Hudi tables as Iceberg for Snowflake consumption. Moral of the story: pick for tomorrow's query engines, not just today's.
The opposite pattern: a B2B SaaS with a classic Medallion architecture on Spark. They picked Iceberg in 2023. Their CDC-heavy bronze layer had some write-amplification pain early on because they were treating Iceberg like it was optimized for their use case. Once they tuned their MERGE batching and added rewrite_data_files maintenance, it was fine. But they admitted in retrospect that Hudi MoR might have saved them 30% on writes.
rewrite_data_files and expire_snapshots.Both formats are production-ready in 2026, and both are ACID, open, and Apache-governed. But they optimize for genuinely different use cases, and that's still the key to picking.
Choose Apache Iceberg if:
If I were starting a new lakehouse green-field in 2026, my default is Iceberg. Not because it's technically superior on every axis — it isn't — but because the ecosystem gravity is undeniable, and being stranded on the non-majority format is a real operational tax. The exception is if I knew from day one that my dominant workload was continuous high-frequency upserts with sub-minute SLAs and a Spark-only query story. In that narrow case, Hudi is still the right tool.
You don't have to pick only one. I've seen teams use Hudi for the landing/bronze layer (where freshness and upserts matter) and transform into Iceberg for silver/gold layers (where engine interop matters). It's more complex than picking one, but if your pain points cleanly split by layer, it can work well. Similarly, Apache XTable (née OneTable) now ships translations between Hudi, Iceberg, and Delta metadata on the same Parquet files — worth a look if you truly need polyglot support.
Use Hudi when your primary workload is high-frequency CDC ingestion with sub-minute freshness SLAs and heavy upsert/delete traffic. Hudi's Merge on Read tables let you absorb writes fast by appending delta logs and merging on read, while async compaction runs in the background. Iceberg can do upserts too, but Hudi was designed for this from day one and its incremental query model (processing only rows changed since a commit) is genuinely unique. If your writes are bulk-append plus occasional MERGE, stick with Iceberg.
There's no one-click tool, but it's achievable. The pragmatic path: read your Hudi tables in Spark with the Hudi reader, then write to Iceberg format using Iceberg's write API, preserving partition structure. Budget a month for a mid-size migration and expect some schema-mapping cleanup. Apache XTable (formerly OneTable) is also worth evaluating — it generates Iceberg metadata on top of Hudi data files, letting you defer a full rewrite. For teams already on Hudi it's often the fastest way to give Snowflake or Athena access without a full migration.
Not natively. Snowflake's Iceberg support is first-class — you can create Iceberg tables managed by Snowflake or attach external Iceberg tables with a few SQL commands. For Hudi tables you'd need to query them through Spark or Trino, or run an Apache XTable translation layer that exposes Hudi data through Iceberg metadata. If Snowflake interop is on your roadmap, Iceberg is meaningfully easier.
Delta Lake is the third major open table format (originating at Databricks). For a while it was Databricks-specific, but Delta 3.0's UniForm feature generates Iceberg metadata alongside Delta metadata so other engines can read it. Today's real three-way race is Iceberg vs. Hudi vs. Delta. We cover Delta vs. Iceberg in a separate article — short version: Delta is great if you're Databricks-centric, Iceberg is the more neutral choice, Hudi is best for continuous-upsert workloads.
For bulk appends, they're comparable. For continuous upserts, Hudi Merge on Read is often faster because it can append delta logs rather than rewrite entire files. Iceberg's equivalent (merge-on-read via positional deletes) has improved significantly in the last two years and closes much of the gap, but Hudi still has the edge for write-heavy upsert workloads. For write-once-read-many analytical workloads, the difference is negligible.
Table formats are only half the story; you also need a catalog to track which tables exist and their current snapshot pointers. The Iceberg REST Catalog specification defines a standard HTTP API any catalog service can implement, so query engines talk to any catalog the same way. Implementations include AWS Glue, Snowflake Open Catalog (Polaris), Unity Catalog, Nessie, and Tabular. This standardization is a big reason Iceberg's ecosystem is compounding faster than Hudi's. Hudi uses its own metadata timeline with optional Hive Metastore integration, which is less standardized across engines.
Both formats accumulate small files and need maintenance. For Iceberg, you call `rewrite_data_files`, `rewrite_manifests`, and `expire_snapshots` on a schedule (daily or weekly depending on write volume) — typically from Spark, Trino, or Snowflake. For Hudi, compaction and cleaning can run async inside your streaming job, which is operationally nicer but means you have to monitor the job and tune its schedule. Neither is zero-ops. Budget engineering time to set up maintenance from day one — it's the #1 thing teams underestimate on both formats.