This is an automated email from the ASF dual-hosted git repository.

vinothchandar pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/hudi.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new 7d351ca89254 docs(blog): Delta/Iceberg migration guides and CDC 
comparison (#19272)
7d351ca89254 is described below

commit 7d351ca8925424c671d78a3e83743d8f860faad0
Author: vinoth chandar <[email protected]>
AuthorDate: Thu Aug 6 19:50:27 2026 +0530

    docs(blog): Delta/Iceberg migration guides and CDC comparison (#19272)
---
 ...2026-08-04-migrating-from-delta-lake-to-hudi.md | 148 +++++++++++++++++++++
 ...-08-05-migrating-from-apache-iceberg-to-hudi.md | 139 +++++++++++++++++++
 ...2026-08-06-hudi-vs-iceberg-for-cdc-workloads.md | 110 +++++++++++++++
 website/docs/migration_guide.md                    |   7 +
 website/static/llms.txt                            |   3 +
 5 files changed, 407 insertions(+)

diff --git a/website/blog/2026-08-04-migrating-from-delta-lake-to-hudi.md 
b/website/blog/2026-08-04-migrating-from-delta-lake-to-hudi.md
new file mode 100644
index 000000000000..31f5d4c64fb0
--- /dev/null
+++ b/website/blog/2026-08-04-migrating-from-delta-lake-to-hudi.md
@@ -0,0 +1,148 @@
+---
+title: "Migrating from Delta Lake to Apache Hudi"
+excerpt: "A practical guide to moving Delta Lake tables to Apache Hudi — 
metadata-only conversion with Apache XTable, a one-time Spark rewrite, 
validation, and rollback."
+description: "How to migrate Delta Lake tables to Apache Hudi: XTable metadata 
translation with no data rewrite, or a one-time Spark bulk insert — plus 
validation and rollback."
+authors: [sivabalan]
+category: how-to
+image: 
/assets/images/blog/2023-08-09-Lakehouse-Trifecta-Delta-Lake-Apache-Iceberg-and-Apache-Hudi.png
+tags:
+- migration
+- apache xtable
+- delta lake
+- guide
+---
+
+You can migrate a Delta Lake table to Apache Hudi either by translating its 
metadata with [Apache XTable](https://xtable.apache.org) — no data rewrite 
required, since both formats store data as Apache Parquet — or by rewriting the 
table once with a Spark `bulk_insert`; many teams start by running both formats 
side by side via XTable and cut writers over only after validating the Hudi 
side.
+
+That single sentence is the whole decision in miniature, but a production 
migration deserves more care than a summary. This guide walks through why teams 
make this move, the three migration strategies and when each fits, the exact 
XTable and Spark commands involved, the Delta-specific features that need 
per-table attention, and how to validate and — if necessary — roll back. 
Throughout, the framing to keep in mind is that both Delta Lake and Hudi are 
[open table formats](/blog/2026/07/14 [...]
+
+## Why Teams Move from Delta Lake to Hudi
+
+Delta Lake takes a deliberately simple approach on disk and is closely 
integrated with Spark. Teams that migrate to Hudi are usually not fleeing Delta 
so much as reaching for write-side machinery that Hudi builds in:
+
+- **Record-level indexing.** Hudi maintains a [multi-modal indexing 
subsystem](/docs/indexes) — record-level indexes, bloom filters, column 
statistics, expression indexes — inside an internal metadata table. For 
update-heavy workloads such as CDC ingestion, an index that maps record keys to 
file groups means the writer can locate the files affected by an update without 
scanning or joining against the whole table.
+- **Streaming-first Merge-on-Read design.** Hudi's MOR table type absorbs 
updates into compact log files that are compacted asynchronously, decoupling 
write latency from file rewrite cost. Workloads that need minute-level 
freshness under continuous upserts tend to be the strongest motivation for the 
move.
+- **Built-in table services.** Compaction, clustering, cleaning, and indexing 
ship with the project and run inline or asynchronously, without a separate 
orchestration layer or a commercial service to keep tables healthy.
+- **Built-in ingestion tooling.** Hudi Streamer provides a self-contained 
ingestion utility with sources for Kafka, DFS, and JDBC, checkpoint management, 
transformations, and catalog syncing.
+
+These differences are measurable, not just architectural. In benchmarks run 
with the open-source [LakeLoader](https://github.com/onehouseinc/lake-loader) 
framework — Spark 3.5, Hudi 1.1.1, Delta Lake 3.3.2, on S3 — we observed 
roughly 6× lower incremental write latency for Hudi on a 10 TB partitioned fact 
table with skewed updates, and about 5× lower steady-state latency on 
Merge-on-Read tables taking sparse, column-level updates. The workload 
definitions are format-agnostic and repeatab [...]
+
+None of this is a knock on Delta — if your workload is mostly appends with 
occasional merges, run entirely on Spark, and you are happy with your current 
operational model, you may not need to migrate at all. The rest of this guide 
assumes you have concluded the write-side capabilities matter for your workload.
+
+## Understand the Three Migration Options
+
+| | A. XTable metadata translation | B. Full rewrite (Spark bulk insert) | C. 
Incremental dual-write cutover |
+|---|---|---|---|
+| **Data movement** | None — metadata only | Full copy of the table | Full 
copy, spread over time |
+| **Downtime for writers** | None during sync; brief pause at cutover | Pause 
writes during the rewrite (or reconcile a delta) | None — new writer runs in 
parallel |
+| **Resulting table** | Hudi metadata over existing Parquet files | Native 
Hudi table, freshly laid out | Native Hudi table |
+| **Lets you re-key / re-partition / resize files** | No — inherits Delta's 
layout | Yes | Yes |
+| **Reversible** | Trivially — source metadata untouched | Source table left 
intact until decommission | Source table left intact until decommission |
+| **Best for** | Large tables, fast side-by-side evaluation, low-risk cutover 
| Small-to-medium tables, or when you want a clean re-layout | Very large, hot 
tables that cannot pause and need a new layout |
+
+A few rules of thumb. If the table is large and its current Parquet layout is 
acceptable, start with **Option A** — it costs almost nothing to try and keeps 
both formats readable while you evaluate. If the table is small enough that a 
rewrite finishes in an acceptable window, or you want to change record keys, 
partitioning, or file sizes as part of the move, **Option B** is simpler to 
reason about. **Option C** — standing up a parallel Hudi pipeline fed from the 
same upstream source, bac [...]
+
+## Option A: Convert with Apache XTable
+
+[Apache XTable](https://xtable.apache.org) (incubating) is an open source 
project that translates table metadata between Delta Lake, Hudi, and Iceberg in 
any direction, without copying or rewriting data files. For this migration, 
Delta is the source and Hudi is the target. XTable reads the Delta transaction 
log and writes out the equivalent Hudi metadata — schema, commit history, 
partition information, and column statistics — alongside the existing Parquet 
files. (The same tool also work [...]
+
+Create a config file describing the source and target:
+
+```yaml
+# my_config.yaml
+sourceFormat: DELTA
+targetFormats:
+  - HUDI
+datasets:
+  - tableBasePath: s3://bucket/warehouse/orders
+    tableName: orders
+```
+
+Then run the sync with the bundled XTable jar (built from 
[source](https://github.com/apache/incubator-xtable) or downloaded from the 
project's GitHub packages):
+
+```shell
+java -jar path/to/xtable-utilities-bundled.jar --datasetConfig my_config.yaml
+```
+
+When the sync completes, the table's base path contains a `.hoodie` directory 
with Hudi's timeline and metadata, side by side with Delta's `_delta_log`. No 
Parquet file was read or written — the job's runtime scales with the amount of 
metadata (number of files and commits), not with data volume. The same 
directory is now readable as a Delta table *and* as a Hudi table.
+
+Two operational notes, faithful to the [XTable 
documentation](https://xtable.apache.org/docs/how-to):
+
+- **Syncs are repeatable and incremental.** XTable supports incremental sync 
(translating only new commits since the last run) with a fallback to full sync, 
so you can run it on a schedule — or after each Delta commit — to keep the Hudi 
metadata current while the Delta writer keeps running.
+- **Catalog registration is a separate step.** XTable produces metadata in 
storage; to query the table as Hudi from your engines, register it in your 
catalog (Hive Metastore, AWS Glue) using Hudi's catalog sync tools or XTable's 
own catalog sync support. Hudi's [XTable page](/docs/syncing_xtable) shows the 
reverse direction and the Hudi Streamer integration.
+
+## The Catch: Converted vs Native Tables
+
+Here is the honest fine print. A converted table is *readable* as a Hudi table 
— snapshot queries, engine integrations, and catalog syncing all work. But most 
of the reasons you are migrating live on the **write path**: record-level 
indexes are built and maintained by Hudi writers; streaming upserts, MOR log 
files, and table services all require Hudi to be the one committing to the 
table. XTable gives you a Hudi-readable table; it does not retroactively give 
your Delta writer Hudi's writ [...]
+
+So a metadata conversion is the first half of the migration, not the whole 
thing. The second half is the writer cutover, which follows a simple sequence:
+
+1. **Stop the Delta writer.** Pause the job or pipeline committing to the 
Delta table. In-flight data can queue upstream (e.g., in Kafka) during the 
brief window.
+2. **Run a final XTable sync.** Translate the last Delta commits so the Hudi 
metadata reflects the table's final Delta-written state.
+3. **Start the Hudi writer.** Point your pipeline — Spark structured 
streaming, Hudi Streamer, or batch jobs following the [quick start 
guide](/docs/quick-start-guide) — at the same base path, configured with the 
record key, ordering field, and table type you validated beforehand. From this 
commit forward, Hudi owns the table and begins building its indexes and running 
table services on new data.
+
+Until step 1, you can run the two formats side by side indefinitely: Delta 
writers keep writing, XTable keeps both metadata layers in sync, and your 
Hudi-native engines and pipelines read the converted table. That side-by-side 
period is where the de-risking happens — you validate reads, permissions, 
catalog integration, and downstream jobs against real data before any writer 
changes.
+
+## Option B: Full Rewrite with Spark
+
+If the table is modest in size, or you want to change its physical layout — 
different partitioning, tuned file sizes, a proper record key for upserts — a 
one-time rewrite is the simplest path. Read the Delta table with Spark, write 
it back as Hudi using `bulk_insert`, the write operation designed for exactly 
this initial-load case:
+
+```scala
+// spark-shell with both Delta and Hudi bundles on the classpath
+val df = spark.read.format("delta").load("s3://bucket/warehouse/orders")
+
+df.write.format("hudi").
+  option("hoodie.datasource.write.recordkey.field", "order_id").
+  option("hoodie.datasource.write.partitionpath.field", "order_date").
+  option("hoodie.table.ordering.fields", "updated_at").
+  option("hoodie.datasource.write.operation", "bulk_insert").
+  option("hoodie.table.name", "orders").
+  mode("overwrite").
+  save("s3://bucket/warehouse/orders_hudi")
+```
+
+Note that the rewrite lands in a *new* base path, leaving the Delta table 
untouched — that is your rollback story. Choose the record key and ordering 
field deliberately here: the record key drives Hudi's indexing and upsert 
semantics, and the ordering field resolves conflicts between multiple versions 
of the same record (essential for CDC-style sources). Both are covered in the 
[quick start guide](/docs/quick-start-guide). For very large tables, the same 
pattern can be applied partition  [...]
+
+If writers must keep running during a long rewrite, capture the cut point (a 
Delta version), rewrite up to it, then apply the trailing changes to the Hudi 
table before cutover — or accept a short write pause and skip the 
reconciliation entirely.
+
+## Handling Delta-Specific Features Honestly
+
+Metadata translation is possible because both formats describe Parquet files — 
but the formats are not feature-identical, and the mapping has edge cases. Per 
XTable's documented [features and 
limitations](https://xtable.apache.org/docs/features-and-limitations), audit 
each table for the following before choosing Option A:
+
+- **Deletion vectors.** XTable currently syncs Copy-on-Write / read-optimized 
views of tables; Delta deletion vectors are *not* captured by the sync. If a 
Delta table uses deletion vectors, a converted Hudi view could include deleted 
rows. Purge deletion vectors on the Delta side first (rewriting affected files 
so deletes are physically applied), or use the full-rewrite path for those 
tables.
+- **Generated columns.** Generated columns on a Delta source do not carry over 
to the target schema, and partitioning on generated columns has restricted 
support (common date transformations, such as deriving a date partition from a 
timestamp, are handled). Tables that partition on other generated expressions 
need per-table verification or a rewrite.
+- **Column mapping.** Delta's column mapping decouples logical column names 
from the physical names inside Parquet files. Since a converted table reads the 
same physical files, tables with column mapping enabled (typically after column 
renames or drops) deserve explicit schema validation on the Hudi side before 
you rely on them.
+
+The general rule: XTable is faithful for the mainstream case — Parquet data 
files, identity or date-derived partitioning, no unapplied deletion vectors — 
and conservative engineering means *validating each table* rather than assuming 
the mainstream case. The validation checklist below is not optional garnish; it 
is how you catch the exceptions.
+
+## Validation Checklist
+
+Run this per table, during the side-by-side period (Option A) or after the 
rewrite (Option B), before any writer cutover or consumer switch:
+
+1. **Row counts.** `SELECT COUNT(*)` through the Delta path and the Hudi path 
must match at the same sync point.
+2. **Checksums on sample partitions.** Compare aggregate fingerprints — sums, 
min/max of key columns, or a hash aggregate — on a handful of partitions, 
including at least one recently written partition and one old one.
+3. **Schema comparison.** Diff the schemas reported by both formats, paying 
attention to nullability, nested fields, and any renamed columns (see column 
mapping above).
+4. **Query-engine smoke tests.** Run representative queries through every 
engine that will read the Hudi table — Spark, Trino, Presto, Athena, etc. — 
including partition-pruned queries and, if relevant, time travel and 
incremental queries.
+5. **Catalog re-registration.** Register the Hudi table in your catalog and 
confirm downstream tools resolve it: BI connections, dbt sources, 
permissions/grants, and any data-quality jobs pointing at the catalog entry.
+6. **Write-path rehearsal.** Before the real cutover, run the intended Hudi 
writer against a cloned or staging copy and confirm upserts, deletes, and table 
services behave as expected with your chosen keys and configs.
+
+## Rollback: The Source Table Stays Intact
+
+The most underrated property of both migration paths is that they are 
non-destructive. With XTable, the Delta transaction log is never modified — 
Hudi metadata is written *alongside* it, and both remain readable throughout 
the transition. With a full rewrite, the Delta table sits untouched at its 
original path. In either case, rollback before cutover is simply "keep using 
the Delta table," and rollback shortly after cutover means pointing writers 
back at Delta and replaying the handful o [...]
+
+Keep the source Delta table — and its `_delta_log` — until the Hudi table has 
run in production long enough to cover your validation and audit horizon. Only 
then decommission it. Migrations fail safe when deletion is the last step, not 
a side effect.
+
+## Conclusion
+
+The strongest reason this migration is more approachable than it used to be is 
that it is no longer a leap of faith. Because Delta Lake and Hudi both store 
data as Parquet, Apache XTable turns "migrate" into "add a second metadata 
layer and evaluate" — you can read your existing tables as Hudi today, run both 
formats side by side for weeks, validate every engine and consumer, and cut 
writers over only when the evidence says to. And if the evidence says 
otherwise, the Delta table never st [...]
+
+## FAQ
+
+<PostFAQ heading={null} items={[
+  {question: 'Do I have to rewrite my data to move from Delta Lake to Hudi?', 
answer: 'No. Because both formats store data as Apache Parquet, Apache XTable 
can translate the Delta transaction log into Hudi metadata alongside the same 
data files, with no data copying. A full rewrite is only needed if you want to 
change the physical layout, such as partitioning or file sizes, or if the table 
uses features like deletion vectors that the metadata sync does not capture.'},
+  {question: 'Can I run Delta Lake and Hudi side by side on the same table?', 
answer: 'Yes. XTable writes Hudi metadata next to the existing Delta log, so 
the same directory is readable as both a Delta table and a Hudi table. You can 
keep the Delta writer running and re-run XTable incrementally to keep both 
metadata layers in sync while you validate the Hudi side, which is the 
recommended de-risking approach before any writer cutover.'},
+  {question: 'Will my Databricks jobs still work after migrating to Hudi?', 
answer: 'Read-only jobs can keep working if you sync the Hudi table back to 
Delta with XTable, since Databricks then reads familiar Delta metadata. Jobs 
that write to the table must be moved to Hudi writers, and Databricks-specific 
features tied to Delta, such as deletion vectors or certain Unity Catalog 
integrations, do not carry over. Treat every Databricks job as something to 
test explicitly during the side-by [...]
+  {question: 'How long does an XTable conversion take?', answer: 'The sync 
reads and writes table metadata only, so its runtime scales with the number of 
files and commits rather than with data volume. That makes it dramatically 
faster than rewriting the data, and incremental sync keeps subsequent runs 
short by translating only new commits.'},
+  {question: 'What happens to my Delta table history and time travel?', 
answer: 'The Delta transaction log is left untouched, so Delta-side history 
remains fully intact and queryable until you decommission the table. The Hudi 
table maintains its own timeline going forward, and it is prudent to keep the 
original Delta log around through your audit and validation horizon before 
deleting anything.'},
+  {question: 'What if my Delta table uses deletion vectors?', answer: 'XTable 
currently syncs Copy-on-Write or read-optimized views, and Delta deletion 
vectors are not captured by the sync, so a converted view could expose deleted 
rows. Purge the deletion vectors on the Delta side first so deletes are 
physically applied to the Parquet files, or migrate that table with a full 
Spark rewrite instead.'},
+]} />
diff --git a/website/blog/2026-08-05-migrating-from-apache-iceberg-to-hudi.md 
b/website/blog/2026-08-05-migrating-from-apache-iceberg-to-hudi.md
new file mode 100644
index 000000000000..1b626ae7d035
--- /dev/null
+++ b/website/blog/2026-08-05-migrating-from-apache-iceberg-to-hudi.md
@@ -0,0 +1,139 @@
+---
+title: "Migrating from Apache Iceberg to Apache Hudi"
+excerpt: "A practical guide to adopting Apache Hudi on existing Iceberg tables 
— via XTable metadata translation or a one-time rewrite — while keeping every 
Iceberg-based reader working through reverse sync."
+description: "How to migrate Iceberg tables to Apache Hudi with XTable 
metadata conversion or a Spark rewrite, keeping Snowflake, BigQuery and Trino 
Iceberg readers working."
+authors: [sivabalan]
+category: how-to
+image: 
/assets/images/blog/2025-07-02-Lakehouse-Architecture-apache-hudi-and-apache-iceberg.png
+tags:
+- migration
+- apache xtable
+- apache iceberg
+- guide
+---
+
+You can adopt Apache Hudi on an existing Apache Iceberg table either by 
translating its metadata with [Apache XTable](https://xtable.apache.org) — no 
data rewrite, since both formats store data as Parquet files — or via a 
one-time rewrite; and because XTable also works in the reverse direction, 
projecting a Hudi table back out as Iceberg, your existing Iceberg readers can 
keep working after the switch. That second point changes the shape of the whole 
exercise. "Migrating from Iceberg to  [...]
+
+This guide walks through both migration options with working configuration and 
code, the cutover sequence that de-risks the switch, an honest look at which 
Iceberg features do not map one-to-one, and a validation checklist with a 
rollback story. It is the Iceberg-side companion to our guides on [using Hudi 
with Apache Iceberg via 
XTable](/blog/2026/07/28/using-hudi-with-apache-iceberg-via-xtable) and 
[migrating from Delta Lake to 
Hudi](/blog/2026/08/04/migrating-from-delta-lake-to-hudi).
+
+## Why Teams Move from Iceberg to Hudi
+
+The migrations we see are almost always driven by the write side. Apache 
Iceberg has broad catalog and engine support, and for append-mostly batch 
analytics it serves many teams fine. The friction shows up when workloads 
become mutation-heavy or latency-sensitive:
+
+- **Record-level indexes for fast upserts.** Hudi maintains a [multi-modal 
indexing subsystem](/docs/indexes) — record-level index, bloom filters, 
expression and secondary indexes — that maps record keys to file groups. An 
upsert locates exactly the files it must touch instead of planning a join or 
scan against the target to find matching rows. For CDC pipelines applying 
millions of scattered updates, this is routinely the difference between minutes 
and hours.
+- **Merge-on-Read designed for streaming ingest.** Hudi's MOR tables absorb 
updates as compact log files merged on read, so writers sustain high-frequency 
commits — minute-level or faster from Kafka, Flink or Spark Structured 
Streaming — without churning out rewritten Parquet on every batch.
+- **Built-in table services.** Compaction, clustering, cleaning and file 
sizing are part of the Hudi runtime and run inline or asynchronously without 
external orchestration. With Iceberg, that maintenance is left to engines, 
scheduled Spark procedures or a vendor service — someone has to own it.
+- **CDC-grade change streams.** Hudi tables serve [incremental 
queries](/docs/sql_queries#incremental-query): give me exactly the records that 
changed between two points on the timeline, including before/after images in 
CDC mode. Downstream pipelines chain off tables directly instead of re-reading 
snapshots and diffing.
+
+The gap is measurable. In benchmarks run with the open-source 
[LakeLoader](https://github.com/onehouseinc/lake-loader) framework — Spark 3.5, 
Hudi 1.1.1, Iceberg 1.10.0, on S3 — we observed roughly 4× lower incremental 
write latency for Hudi on a 10 TB partitioned fact table with skewed updates, 
and about 8× lower steady-state latency on Merge-on-Read tables taking sparse, 
column-level updates, with Hudi's record-level index sidestepping the 
full-table-scan merge joins that dominate the  [...]
+
+The point is not that Iceberg cannot handle these workloads — it is that 
Hudi's write path, indexing and self-managing services are built for mutable, 
streaming-oriented workloads. If that describes the tables you are running, 
here is how to move them.
+
+## Migrate the Writer, Keep the Readers
+
+The biggest source of migration risk is rarely the table itself — it is the 
long tail of consumers. A warehouse reading through an Iceberg catalog, BI 
dashboards, other teams' Spark jobs. A migration plan that requires all of them 
to change on cutover day is fragile enough that most teams never start.
+
+The two-way XTable pattern removes that requirement:
+
+1. **Writers move to Hudi.** Your ingestion pipeline gains Hudi's upsert 
indexes, MOR streaming writes and table services.
+2. **XTable continuously projects the Hudi table back out as Iceberg.** After 
each Hudi commit (or on a schedule), XTable translates the Hudi timeline into 
Iceberg metadata over the *same* Parquet data files, and its catalog sync can 
keep Hive Metastore or AWS Glue entries current.
+3. **Readers keep reading Iceberg.** Snowflake, BigQuery, Trino Iceberg 
catalogs, anything else that only speaks Iceberg — all keep working. They can 
each move to native Hudi reads later, on their own schedule, or never.
+
+Because the data files are shared and only lightweight metadata is generated, 
the reverse projection is cheap and stays fresh. The migration decision 
decomposes: the writer cutover is one contained change, and every reader 
migration becomes optional and independent. We cover the reader-side mechanics 
in depth in the [Hudi + Iceberg interoperability 
guide](/blog/2026/07/28/using-hudi-with-apache-iceberg-via-xtable); the rest of 
this post focuses on getting the table and the writer onto Hudi.
+
+## Option A: Convert Iceberg Metadata to Hudi with Apache XTable
+
+XTable (incubating) translates table metadata between Hudi, Iceberg and Delta 
Lake in any direction. Pointed at an Iceberg table, it reads the Iceberg 
snapshot and writes Hudi metadata — a `.hoodie` timeline with schema, commit 
history, partition and column statistics — referencing the existing Parquet 
files in place. Nothing is copied or rewritten.
+
+Grab the XTable bundled jar (build from 
[source](https://github.com/apache/incubator-xtable) or download from GitHub 
packages) and create a config:
+
+```yaml md title="iceberg_to_hudi.yaml"
+sourceFormat: ICEBERG
+targetFormats:
+  - HUDI
+datasets:
+  -
+    tableBasePath: s3://warehouse/orders
+    tableDataPath: s3://warehouse/orders/data
+    tableName: orders
+    partitionSpec: order_date:VALUE
+```
+
+`tableDataPath` is needed for Iceberg sources when data files live under a 
subdirectory (the layout Iceberg warehouses typically use) rather than directly 
under the base path. Then run the sync:
+
+```shell
+java -jar path/to/xtable-utilities-bundled.jar --datasetConfig 
iceberg_to_hudi.yaml
+```
+
+The run produces Hudi metadata under the table's base path. Any Hudi-capable 
engine can now read the table — the same files your Iceberg readers are still 
using. XTable syncs incrementally by default (translating only new commits, 
falling back to a full sync when needed), so re-running it on a schedule keeps 
the Hudi view current for as long as the Iceberg writer remains active. 
Registering the table in your catalog of choice makes it visible to Hudi 
readers alongside the existing Iceber [...]
+
+At this stage you have a zero-copy, read-ready Hudi table and have changed 
nothing about production. That alone is useful — you can benchmark Hudi readers 
against real data before committing to anything.
+
+## Converted vs Native: Cutting the Writer Over
+
+Metadata translation gets you Hudi *reads*. The features that motivate the 
migration — record-level index lookups, streaming upserts, change streams, 
self-managing table services — come from Hudi *writing* the table: assigning 
record keys, maintaining indexes and the metadata table, running services 
against its own timeline. To get them, you cut the writer over. The sequence:
+
+1. **Stop the Iceberg writer.** Pause ingestion at a clean commit boundary.
+2. **Run a final XTable sync** (Iceberg → Hudi) so the Hudi metadata reflects 
the last Iceberg commit exactly.
+3. **Start the Hudi writer** against the table's base path, configuring the 
record key, ordering fields (`hoodie.table.ordering.fields`) and partitioning 
to match your workload. From here, commits land natively on the Hudi timeline, 
indexes are built and maintained, and table services take over maintenance.
+4. **Enable reverse sync** (Hudi → Iceberg) — via the XTable job on a schedule 
with `sourceFormat: HUDI`, or per-commit through the Hudi Streamer sync 
extension ([docs](/docs/syncing_xtable)) — so Iceberg readers see every new 
Hudi commit.
+
+The gap between steps 1 and 4 is minutes of paused ingestion, not a data-copy 
window — for most tables the downtime is a single deferred micro-batch. 
Validate the native-write onboarding on a staging copy first: depending on the 
table's layout and key structure, some tables are better served by Hudi's 
[bootstrap mechanism](/docs/migration_guide) or a full rewrite (Option B below) 
to get a fully native file layout with populated Hudi metadata fields, rather 
than writing directly on top of [...]
+
+## Option B: One-Time Rewrite with Spark
+
+If the table is modest in size, or you want to change its physical layout 
anyway — new partitioning, clustering by query predicates, cleaning out 
accumulated small files — a full rewrite is the simpler and sometimes better 
move. Read the Iceberg table with Spark, write a Hudi table:
+
+```scala
+// spark-shell with both Iceberg and Hudi bundles on the classpath
+val df = spark.read.format("iceberg").load("s3://warehouse/orders")
+
+df.write.format("hudi").
+  option("hoodie.table.name", "orders").
+  option("hoodie.datasource.write.recordkey.field", "order_id").
+  option("hoodie.datasource.write.partitionpath.field", "order_date").
+  option("hoodie.table.ordering.fields", "updated_at").
+  option("hoodie.datasource.write.operation", "bulk_insert").
+  mode("overwrite").
+  save("s3://warehouse/orders_hudi")
+```
+
+This is a plain batch job — parallelize by partition for very large tables, as 
shown in the [migration guide](/docs/migration_guide), which also covers Hudi 
Streamer's bootstrap mode (including METADATA_ONLY, which builds skeleton files 
instead of rewriting data). The rewrite costs a full pass over the data but 
produces a completely native Hudi table with no conversion caveats, and cutover 
is just repointing the writer and backfilling the delta that accrued during the 
copy. See the [Spar [...]
+
+## What May Not Map One-to-One
+
+An honest migration plan checks feature parity per table rather than assuming 
it. Watch for:
+
+- **Merge-on-read delete files.** XTable syncs the underlying Parquet data 
files; Iceberg v2 position/equality delete files are not carried through the 
conversion. Compact them away first (e.g. Iceberg's `rewrite_data_files` / 
`rewrite_position_delete_files` procedures) so the source snapshot is 
materialized in data files before converting. The same applies to newer v3 
constructs such as deletion vectors.
+- **Hidden partitioning and partition evolution.** Iceberg partitions by 
column transforms (`days(ts)`, `bucket(n, id)`) invisible to queries, and lets 
the partition spec evolve over time. Hudi partitions by explicit partition path 
fields. Simple value and date-based partitioning translate cleanly; bucket 
transforms and tables carrying multiple historical partition specs need 
per-table validation, and a rewrite (Option B) into a layout of your choosing 
is often the cleaner answer for them.
+- **Iceberg-specific column types and metadata.** Features tied to recent 
Iceberg spec versions — row lineage, variant type in v3, engine-specific 
catalog behaviors — have no direct Hudi equivalent or map differently. 
Inventory what each table actually uses; most analytics tables use none of 
these.
+- **Snapshot history.** The converted Hudi table's timeline starts at 
conversion. Old Iceberg snapshots remain time-travelable through the Iceberg 
metadata (which stays intact on storage), but do not appear as Hudi commits.
+
+None of these block a migration; they determine which tables take the 
metadata-translation fast path and which deserve a rewrite.
+
+## Validation Checklist and Rollback
+
+Before decommissioning anything, verify per table:
+
+- **Row counts and checksums** match between the Iceberg source and Hudi 
target (and, after cutover, between the Hudi table and its reverse-synced 
Iceberg projection).
+- **Schema fidelity** — column types, nullability and nested structures 
survived translation.
+- **Partition pruning** works: run a partition-filtered query against the Hudi 
table and confirm file skipping.
+- **Reader smoke tests** from every consumer that matters: native Hudi reads 
from Spark/Trino, and Iceberg reads from the warehouse or catalog your 
downstream teams use.
+- **Writer dry run** on staging: upsert, delete, then read back and confirm 
index behavior and table service activity on the timeline.
+
+The rollback story is what makes this migration low-stakes. Until you delete 
it, the original Iceberg metadata is untouched — XTable conversion writes new 
metadata alongside, and Option B writes to a new path entirely — so reverting 
before cutover means simply not proceeding. After cutover, reverse sync means 
there is a live, continuously updated Iceberg view of the table at all times: 
if a downstream Iceberg consumer misbehaves, it keeps reading Iceberg while you 
debug, and in the worst [...]
+
+## Conclusion
+
+Table format choice used to be a one-way architectural door; XTable makes it a 
revolving one. Adopting Hudi on an Iceberg estate is not a monolithic rewrite: 
translate metadata in place to light up Hudi reads, cut writers over 
table-by-table to gain [indexes](/docs/indexes), streaming upserts and built-in 
table services, and let reverse sync keep every Iceberg-based consumer running 
exactly as before. Rewrite the tables that want a new layout; translate the 
rest. Start with one mutation- [...]
+
+## FAQ
+
+<PostFAQ heading={null} items={[
+  {question: 'Can Snowflake still read my table after migrating to Hudi?', 
answer: 'Yes. Apache XTable can continuously project a Hudi table back out as 
Iceberg metadata over the same Parquet data files, and can sync catalogs like 
AWS Glue or Hive Metastore. Snowflake, BigQuery and other engines that read 
Iceberg keep working against that projection, so reader migrations become 
optional and can happen on their own schedule.'},
+  {question: 'Does migrating from Iceberg to Hudi require rewriting data?', 
answer: 'Not necessarily. Both formats store data as Parquet files, so Apache 
XTable can translate the Iceberg metadata into a Hudi timeline referencing the 
existing files in place, with no data copy. A full rewrite via Spark is only 
needed when you want to change the physical layout, such as new partitioning or 
clustering, or for tables whose Iceberg features don\'t translate cleanly.'},
+  {question: 'What do I gain by moving the write path to Hudi?', answer: 
'Hudi\'s writer maintains record-level and bloom indexes that make scattered 
upserts fast, supports Merge-on-Read tables built for high-frequency streaming 
ingestion, runs compaction, clustering and cleaning as built-in table services, 
and serves incremental and CDC queries off its timeline. These come from Hudi 
writing the table, which is why the cutover targets writers first.'},
+  {question: 'Can I go back to Iceberg if the migration doesn\'t work out?', 
answer: 'Yes. The original Iceberg metadata stays intact on storage until you 
delete it, so before cutover, rollback means simply not proceeding. After 
cutover, reverse sync maintains a live Iceberg view of the table at all times, 
so in the worst case you can resume Iceberg-native writes from the current 
state rather than restoring from backups.'},
+  {question: 'How much downtime does the writer cutover take?', answer: 
'Minutes, not hours. The sequence is: pause the Iceberg writer at a commit 
boundary, run a final XTable sync so the Hudi metadata matches exactly, start 
the Hudi writer, and enable reverse sync from Hudi back to Iceberg. There is no 
data copy in that window, so the downtime is typically a single deferred 
micro-batch.'},
+  {question: 'Do Iceberg v2 delete files survive the conversion?', answer: 
'No. XTable syncs the underlying Parquet data files, and Iceberg position or 
equality delete files are not carried through. Run Iceberg\'s compaction 
procedures to materialize deletes into data files before converting, so the 
snapshot XTable translates is fully represented in Parquet.'},
+]} />
diff --git a/website/blog/2026-08-06-hudi-vs-iceberg-for-cdc-workloads.md 
b/website/blog/2026-08-06-hudi-vs-iceberg-for-cdc-workloads.md
new file mode 100644
index 000000000000..389586c2462d
--- /dev/null
+++ b/website/blog/2026-08-06-hudi-vs-iceberg-for-cdc-workloads.md
@@ -0,0 +1,110 @@
+---
+title: "Apache Hudi vs Apache Iceberg for CDC Workloads"
+excerpt: "A mechanism-level comparison of how Apache Hudi and Apache Iceberg 
handle change data capture: record lookup, deletes, small files, ordering and 
change streams."
+description: "Hudi vs Iceberg for CDC: how each handles record lookups, 
deletes, small files, ordering and change streams — and a framework for 
choosing between them."
+authors: [sivabalan]
+category: deep-dive
+image: /assets/images/blog/2024-12-03-apache-iceberg-vs-apache-hudi.jpeg
+tags:
+- comparison
+- apache iceberg
+- cdc
+- data lakehouse
+---
+
+Both Apache Hudi and Apache Iceberg can ingest change data capture (CDC) 
streams, but they were designed around different problems. Hudi was built for 
mutation-heavy ingestion: a record-level index that locates any key without 
scanning the table, merge-on-read delta logs that absorb frequent updates and 
deletes cheaply, and built-in deduplication, ordering and file sizing. Iceberg 
was designed first for large, reliable analytical scans; its copy-on-write and 
delete-file-based merge-on-re [...]
+
+<!--truncate-->
+
+## What CDC demands from a table format
+
+A CDC stream is, by construction, mostly mutations. If you replicate an 
operational database to the lake (the basics are covered in [What is CDC on a 
Data Lake?](/blog/2026/07/22/what-is-cdc-on-a-data-lake) and the deeper 
[Understanding Data Lake Change Data Capture](/blog/2024/07/30/data-lake-cdc)), 
the table format underneath has to sustain a specific set of pressures:
+
+- **Fast key-based upserts and deletes.** Every change event targets one row 
identified by a primary key. The write path must find where that key lives and 
apply the change without rewriting or rescanning unrelated data.
+- **Ordering and late data.** Events arrive out of order after retries and 
repartitioning. The format must merge by the source's log position or event 
time, not arrival time, or the table silently regresses.
+- **Frequent small commits.** Minute-level freshness means committing every 
few minutes, around the clock. That stresses metadata, file counts and any 
background maintenance.
+- **Change streams for downstream consumers.** Bronze tables that absorb CDC 
should also *emit* changes, so silver and gold tables can be built 
incrementally instead of re-reading everything.
+
+Hold each format against these four demands and the architectural differences 
become concrete.
+
+## Finding the record: indexes vs. joins
+
+The first job in applying an upsert is answering "which file contains this 
key?"
+
+**Hudi** treats indexing as a core component of the write path. Every record 
key maps to exactly one file group, and Hudi maintains [pluggable 
indexes](/docs/indexes) — bloom-filter, simple-join, bucket-hash and, since 
0.14.0, a record-level index stored inside the table's metadata table — that 
resolve incoming keys to their file groups directly. With the record-level 
index, lookup cost is proportional to the number of records changed, not the 
size of the table: the writer consults hash- [...]
+
+**Iceberg** deliberately has no record-level index; its metadata tree 
(manifests, partition values, column min/max stats) is built for pruning scans, 
not locating keys. A `MERGE INTO` in Spark plans a join between the incoming 
batch and the target table to discover which files hold matching rows — column 
statistics can prune files, but for keys spread across a table the merge 
effectively scans and joins against much of it. Streaming writers such as 
Flink's Iceberg sink in upsert mode sid [...]
+
+This difference is measurable, and you can reproduce it. In benchmarks run 
with the open-source [LakeLoader 
framework](https://github.com/onehouseinc/lake-loader) (Spark 3.5, Hudi 1.1.1, 
Iceberg 1.10.0), we observed Hudi delivering roughly 4× lower incremental write 
latency than Iceberg on a 10 TB partitioned table under skewed CDC-style 
updates — the record-level index shuffled around 250 MB per commit where the 
merge join shuffled hundreds of gigabytes — and roughly 8× lower steady-sta 
[...]
+
+## How deletes actually work
+
+Deletes are where CDC pipelines live or die, since every update in a changelog 
is logically a delete plus an insert of the new version.
+
+**Hudi** logs a delete into the same file group where the key lives, exactly 
like an update. On a merge-on-read table this is an append to that file group's 
delta log; queries merge base file plus log at read time within the file group, 
and compaction later rewrites the base file with the deletes applied. Because 
deletes are colocated with the data they affect, the merge scope is always one 
base file against its own changes — never a table-wide reconciliation. Data 
locality is preserved  [...]
+
+**Iceberg** (format v2) represents row-level deletes as separate delete files 
of two kinds. *Position deletes* name a row by data file path and row ordinal — 
precise and cheap to apply on read, but the writer must first find the row, 
which without an index means the join described above. *Equality deletes* 
record column predicates and are cheap to write, but every reader must check 
each equality delete file against every data file with an older sequence number 
in its scan. When many data [...]
+
+The Iceberg community has been working on this. Format v3 replaces position 
delete files with binary *deletion vectors* — at most one compact bitmap per 
data file — which removes much of the position-delete proliferation and 
read-time association cost, and engines are adopting it. But deletion vectors 
help the position-delete path; a writer still needs to determine which 
positions to delete, so the no-index lookup cost remains, and equality deletes 
still defer their cost to readers and c [...]
+
+## Commit frequency and small files
+
+CDC means committing every few minutes, forever. Two things degrade under that 
regime: file sizes and metadata.
+
+**Hudi** performs automatic file sizing during writes — small inserts are 
bin-packed into existing under-sized file groups, so frequent commits do not 
proliferate small files in the first place. Its cleaner bounds how many old 
file versions are retained, and timeline archival keeps the active timeline 
small, all running as managed table services alongside ingestion.
+
+**Iceberg** produces at least one new data file (and, in merge-on-read, delete 
files) plus a new snapshot per commit. Nothing in the write path resizes files, 
so a minute-level stream steadily accumulates small data files, delete files 
and snapshot metadata. The remedies exist — `rewrite_data_files` for 
compaction, `expire_snapshots`, `rewrite_manifests`, 
`rewrite_position_delete_files` — but they are maintenance procedures you 
schedule and size yourself, and under optimistic concurrency [...]
+
+## Ordering, dedup and partial updates
+
+Changelogs carry semantics beyond "latest write wins."
+
+**Hudi** requires a record key and supports an ordering (precombine) field as 
first-class table concepts. Multiple events for the same key within a batch are 
deduplicated by ordering value before write; a late-arriving event with an 
older ordering value than what's stored is dropped rather than applied, so 
out-of-order delivery cannot regress the table. Record merger and payload APIs 
go further: partial updates merge only the non-null incoming fields into the 
existing row, and custom mer [...]
+
+**Iceberg** does not define keys, dedup or ordered merging at the format level 
— it stores what engines write. Spark's `MERGE INTO` will fail if multiple 
source rows match one target row, so deduplication and event-time ordering must 
be implemented upstream in the pipeline; Flink's upsert mode assumes the stream 
itself is correctly ordered per key within its checkpoint discipline. That is a 
deliberate design choice — the format stays engine-neutral — but it means every 
CDC pipeline re-im [...]
+
+## Producing change streams downstream
+
+A CDC-fed bronze table is usually the head of a pipeline, so how each format 
*emits* changes matters as much as how it absorbs them.
+
+**Hudi** keeps commit-time metadata on every record and supports [incremental 
queries](/docs/table_types) as a native query type: give a begin instant, get 
exactly the records that changed since, at any commit granularity. Since 0.13.0 
a CDC query mode also returns database-style before/after images with the 
operation type, logged at write time. Downstream jobs chain these into 
incremental ETL, each layer consuming only deltas.
+
+**Iceberg** supports incremental scans between snapshots, which cover 
append-only snapshots; consuming row-level changes from snapshots that carry 
updates and deletes is harder, and Spark's `create_changelog_view` procedure 
computes a changelog view by diffing snapshots — with pre/post images available 
as an optional, more expensive computation — rather than reading changes that 
were logged at write time. For append-mostly tables the two are comparable; for 
update-heavy tables, deriving  [...]
+
+## Operational reality
+
+What do you actually run in production?
+
+A Hudi ingestion job carries its table services with it: compaction, 
clustering, cleaning, file sizing and archival are scheduled and executed by 
the platform, inline or async, with [MVCC coordinating writers and table 
services](/docs/concurrency_control) so compaction does not block ingestion — 
plus non-blocking concurrency control (since 1.0) for multiple writers, and 
early conflict detection that aborts a doomed write mid-flight instead of at 
commit, saving the wasted compute. The ing [...]
+
+An Iceberg deployment composes the equivalent from parts: an orchestrator (or 
a managed catalog service) running compaction, snapshot expiry, delete-file 
rewrites and manifest rewrites at the right cadence for your commit rate, with 
conflict-retry behavior tuned so maintenance and streaming writers coexist. 
None of this is exotic, and managed platforms increasingly automate it — but on 
a high-frequency CDC table the maintenance cadence is unforgiving, and it is 
your pager when it falls behind.
+
+## A decision framework
+
+Honest summary rather than a scorecard:
+
+**Iceberg is a workable choice when** your CDC is low-frequency (hourly or 
slower batches), tables are append-mostly with modest update ratios, you 
already operate an Iceberg estate with maintenance automation in place, or 
organizational standardization on one format outweighs per-workload 
optimization. The v3 deletion-vector work also means the read-side delete 
overhead is shrinking release by release.
+
+**Hudi pulls ahead when** update/delete ratios are high (mirroring OLTP 
tables, not appending events), you need sub-hour freshness with commits every 
few minutes, keys are spread across the table so per-write lookup cost 
dominates, or downstream consumers need true record-level change streams. These 
are exactly the pressures Hudi's index, delta logs, precombine semantics and 
managed services were designed against.
+
+## It's Not Either/Or: Interoperability via Apache XTable
+
+The framing of this post — pick one format — understates a practical third 
option. The formats' metadata layers describe data files; the data files 
themselves are Parquet either way. [Apache XTable](https://xtable.apache.org/) 
(incubating) exploits this by translating table metadata between Hudi, Iceberg 
and Delta Lake without copying data, so a single physical table can be read 
through more than one format's metadata.
+
+For CDC specifically, that enables a concrete pattern: ingest with Hudi to get 
the record-level index, log-based deletes, auto file sizing and incremental 
queries on the write-heavy bronze layer, then run XTable to expose the same 
data as Iceberg metadata for engines and catalogs that only speak Iceberg — 
Snowflake, BigQuery, or an existing Iceberg-standardized analytics stack. The 
translation is incremental (it processes only new commits) and involves no data 
rewrite, since both formats [...]
+
+This decouples the write-path decision from the read-path decision. Choose the 
ingestion machinery on the merits of your CDC workload, and serve readers in 
whatever format they require. We cover the setup end-to-end in [Using Hudi with 
Apache Iceberg via 
XTable](/blog/2026/07/28/using-hudi-with-apache-iceberg-via-xtable).
+
+## Conclusion
+
+Hudi and Iceberg will both land a CDC stream. The difference is where the cost 
of mutation is paid. Hudi pays it at write time with machinery built for the 
purpose — an index that finds keys in O(changes), delta logs that keep deletes 
local to their file group, ordering and dedup in the format, file sizing and 
compaction as built-in services. Iceberg defers it — to read-time delete 
reconciliation, to maintenance jobs, to pipeline-level dedup logic — a trade 
that suits scan-heavy, append- [...]
+
+## FAQ
+
+<PostFAQ heading={null} items={[
+  {question: 'Is Apache Iceberg good for CDC?', answer: 'Iceberg can handle 
CDC, and it works well when changes arrive in low-frequency batches or tables 
are append-mostly. For high-frequency, update-heavy streams, the lack of a 
record-level index makes merges join against the table, delete files accumulate 
between compactions, and you must schedule maintenance jobs aggressively. 
Iceberg v3\'s deletion vectors improve the read-side cost, but the write-side 
lookup and maintenance burden r [...]
+  {question: 'Why is Hudi faster for upserts than Iceberg?', answer: 'Hudi 
maintains indexes, including a record-level index, that map each record key 
directly to the file group holding it, so an upsert touches only the files that 
actually contain changed keys and lookup cost scales with the size of the 
change batch. Iceberg has no record index, so finding the rows to update 
requires joining the incoming batch against the target table. On merge-on-read 
tables Hudi also appends changes to [...]
+  {question: 'How do deletes differ between Hudi and Iceberg?', answer: 'Hudi 
logs a delete into the same file group where the record lives, and compaction 
later applies it while rewriting that one base file, so merge scope stays 
local. Iceberg v2 writes separate position or equality delete files that 
readers and compaction jobs must reconcile against data files, a cost that 
grows as both accumulate. Iceberg v3 replaces position delete files with 
per-file deletion vectors, which meaningf [...]
+  {question: 'Can I use Hudi for CDC ingestion and still serve Iceberg 
readers?', answer: 'Yes. Apache XTable translates Hudi table metadata into 
Iceberg metadata incrementally, without copying or rewriting the underlying 
Parquet data files. You get Hudi\'s indexed upserts, delete handling and file 
sizing on the write path, while Iceberg-only engines and catalogs read the same 
table through Iceberg metadata.'},
+  {question: 'Does Iceberg support incremental reads like Hudi?', answer: 
'Partially. Iceberg supports incremental scans over append snapshots, and Spark 
can build a changelog view by diffing snapshots, with before/after images as an 
extra computation. Hudi records commit metadata on every record and logs change 
data at write time, so incremental and CDC queries read changes directly 
instead of deriving them, which matters most on update-heavy tables.'},
+]} />
diff --git a/website/docs/migration_guide.md b/website/docs/migration_guide.md
index 513a201e6672..831f0d7c74a1 100644
--- a/website/docs/migration_guide.md
+++ b/website/docs/migration_guide.md
@@ -121,6 +121,13 @@ Here are the basic configs that control bootstrapping.
 By default, with only `hoodie.bootstrap.base.path` being provided 
METADATA_ONLY mode is selected. For other options, please refer [bootstrap 
configs](https://hudi.apache.org/docs/next/configurations#Bootstrap-Configs) 
for more details.
 
 ## Related Resources
+<h3>Step-by-step migration guides</h3>
+
+* [Migrating from Parquet to Apache 
Hudi](https://hudi.apache.org/blog/2026/07/29/migrating-from-parquet-to-hudi)
+* [Migrating from Apache Hive Tables to Apache 
Hudi](https://hudi.apache.org/blog/2026/07/30/migrating-from-hive-to-hudi)
+* [Migrating from Delta Lake to Apache 
Hudi](https://hudi.apache.org/blog/2026/08/04/migrating-from-delta-lake-to-hudi)
+* [Migrating from Apache Iceberg to Apache 
Hudi](https://hudi.apache.org/blog/2026/08/05/migrating-from-apache-iceberg-to-hudi)
+
 <h3>Videos</h3>
 
 * [Bootstrapping in Apache Hudi on EMR Serverless with 
Lab](https://www.youtube.com/watch?v=iTNLqbW3YYA)
diff --git a/website/static/llms.txt b/website/static/llms.txt
index 5177506057f8..f8fbfb4df255 100644
--- a/website/static/llms.txt
+++ b/website/static/llms.txt
@@ -53,9 +53,12 @@ It can also synchronize your data to half dozen data 
catalogs to keep table cons
 
 - [Migrating from Parquet to 
Hudi](https://hudi.apache.org/blog/2026/07/29/migrating-from-parquet-to-hudi): 
In-place bootstrap vs full rewrite for converting raw Parquet datasets into 
Hudi tables.
 - [Migrating from Hive to 
Hudi](https://hudi.apache.org/blog/2026/07/30/migrating-from-hive-to-hudi): 
Moving Hive tables to Hudi with bootstrap and catalog sync.
+- [Migrating from Delta Lake to 
Hudi](https://hudi.apache.org/blog/2026/08/04/migrating-from-delta-lake-to-hudi):
 Metadata conversion with Apache XTable or full rewrite, step by step.
+- [Migrating from Apache Iceberg to 
Hudi](https://hudi.apache.org/blog/2026/08/05/migrating-from-apache-iceberg-to-hudi):
 Keep Iceberg readers working via XTable while adopting Hudi's write path.
 
 ## Blog — Comparisons
 
+- [Hudi vs Iceberg for CDC 
Workloads](https://hudi.apache.org/blog/2026/08/06/hudi-vs-iceberg-for-cdc-workloads):
 Criteria-driven comparison for change-data-capture ingestion.
 - [Hudi vs Delta Lake vs Iceberg Feature 
Comparison](https://hudi.apache.org/blog/2023/01/11/Apache-Hudi-vs-Delta-Lake-vs-Apache-Iceberg-Lakehouse-Feature-Comparison):
 Feature-by-feature comparison of the three open table formats.
 
 ## Blog — Deep dives

Reply via email to