skip to content

Lakehouse Table Formats

You will learn the open table formats — Iceberg, Delta Lake, Hudi — that turn a pile of Parquet files on object storage into a real table with ACID commits, snapshots, schema and partition evolution, and time travel. Interviewers reach for this area because 'lakehouse' is the default modern data-platform answer, and they want to know whether you understand the metadata layer or just the file layer.

on this pageshow

explore

questions

71 · 4 sections

Why does a query engine need a catalog to read a lakehouse table instead of a path?

level: juniorimportance: must knowfreq 60%
basics
~20 s

A catalog maps a table name to the location of that table's current metadata, so every engine agrees on which version is live. A storage path only lists files, including leftovers from failed or in-flight writes that no commit includes.

open as a page

Why do thousands of tiny data files slow down queries on a lakehouse table?

level: juniorimportance: must knowfreq 78%
basics
~20 s

Each file costs fixed overhead: a metadata entry to plan, an object-store request to open, and a footer to parse. With thousands of tiny files that per-file overhead dominates, so the engine spends its time on bookkeeping rather than reading rows.

open as a page

What is the difference between a file format like Parquet and a table format like Iceberg?

level: juniorimportance: must knowfreq 85%
basics
~20 s

A file format defines how bytes are laid out inside one immutable file. A table format is a metadata layer above a set of such files that records which files, which schema and which version make up the table right now.

open as a page

What does Hive-style directory partitioning do to a table's file layout on object storage?

level: juniorimportance: must knowfreq 72%
basics
~10 s

Hive-style partitioning splits a table's files into directories named column=value, such as dt=2024-05-01. A query that filters on that column reads only the matching directories, so it touches a fraction of the table.

open as a page

How does an open lakehouse table format let you query a table as it looked yesterday?

level: juniorimportance: must knowfreq 68%
basics
~20 s

Every write produces a new immutable snapshot: a record of the complete set of data files that form the table at that instant. Older snapshots are kept, so a time-travel query reads an older file list instead of the current one.

open as a page

In Apache Iceberg, which files does the expire_snapshots procedure actually delete?

level: middleimportance: must knowfreq 72%
basics
~20 s

It removes snapshot entries older than the retention window from table metadata, then deletes the data files, delete files, manifests and manifest lists that no remaining snapshot references. Anything still reachable from a kept snapshot survives, whatever its age.

open as a page

In Iceberg, what changes when write.delete.mode is set to merge-on-read?

level: middleimportance: must knowfreq 66%
basics
~20 s

Instead of rewriting every data file that contains a matching row, the engine writes small delete files that mark rows as removed and commits those. Writes get much faster; reads must merge deletes at scan time until compaction materialises them.

open as a page

What happens to existing Iceberg data files when you ALTER TABLE ADD PARTITION FIELD?

level: middleimportance: must knowfreq 72%
basics
~20 s

Nothing is rewritten. Iceberg appends a new partition spec to table metadata and points new writes at it; files already written keep the spec id they were written under, and scan planning handles each spec separately.

open as a page

In Apache Iceberg, what does hidden partitioning change about how a partitioned table is queried?

level: middleimportance: must knowfreq 82%
basics
~10 s

Iceberg derives partition values from a transform on a real column, so queries filter that column and still prune. Hive-style tables need a separate derived column that every reader must remember to filter on.

open as a page

In Apache Iceberg, how does a reader reach the data files a query must scan?

level: middleimportance: must knowfreq 80%
basics
~20 s

The catalog names the current metadata file. That JSON gives the current snapshot, whose manifest-list Avro file names the manifests. Each manifest lists data files with partition values and column bounds, so the reader prunes manifests then files and scans only survivors.

open as a page

In an Apache Hudi write, what do the record key and precombine field control?

level: juniorimportance: must knowfreq 55%
basics
~20 s

The record key is a row's identity, so Hudi can update or delete that row instead of only appending. The precombine field breaks ties between duplicates of a key, keeping the record with the higher value.

open as a page

In Apache Hudi, how does an update reach storage differently under Copy-on-Write and Merge-on-Read?

level: middleimportance: must knowfreq 70%
basics
~20 s

Copy-on-Write merges the update into the base Parquet file and rewrites it as a new file version. Merge-on-Read appends the update as a log block in the same file group, leaving the merge to read time or to a later compaction.

open as a page

In Apache Hudi, what is an instant on the .hoodie timeline?

level: middleimportance: must knowfreq 50%
basics
~20 s

An instant is one entry on the timeline in a Hudi table's .hoodie directory: an action such as commit, deltacommit, compaction or clean, stamped with a monotonic time and a state of requested, inflight or completed.

open as a page

A Hudi Merge-on-Read table's snapshot queries slow down every hour — what would you check?

level: seniorimportance: must knowfreq 55%
basics
~20 s

Almost always compaction is not keeping up, so log files pile up on each file slice and every snapshot query merges more of them. Check the timeline for delta commits since the last completed compaction, then fix scheduling, parallelism or the writer's compaction service.

open as a page

Which Apache Hudi table type is the default, and what does it write on an update?

level: juniorimportance: should knowfreq 52%
basics
~20 s

Copy-on-Write is the default Hudi table type. Updating a record rewrites the whole Parquet base file that holds it as a new file version, so readers just scan the newest base file per file group with no merging.

open as a page

What does a Delta Lake table's _delta_log directory contain?

level: juniorimportance: must knowfreq 72%
basics
~10 s

A Delta table's _delta_log holds the transaction log: numbered JSON commit files listing actions such as add, remove, metaData and protocol, plus periodic Parquet checkpoints and a _last_checkpoint pointer to the newest one.

open as a page

In Delta Lake, what does OPTIMIZE change about a table's data files?

level: middleimportance: must knowfreq 70%
basics
~20 s

OPTIMIZE bin-packs many small Parquet files into fewer large ones (roughly 1 GB by default), committing remove and add actions in a new table version. Row content is unchanged, and the replaced files stay on storage until VACUUM deletes them.

open as a page

In a Delta Lake table, what actions does the _delta_log commit for a row-level DELETE contain?

level: middleimportance: must knowfreq 66%
basics
~20 s

A row-level DELETE on a Delta table without deletion vectors rewrites the affected Parquet file: the commit holds a remove tombstone for the old file path, an add for the freshly written file minus those rows, and a commitInfo entry describing the operation.

open as a page

Why does a Delta Lake time-travel query fail after VACUUM runs?

level: seniorimportance: must knowfreq 62%
basics
~20 s

VACUUM physically deletes data files that the current version no longer references once they are older than the retention threshold (7 days by default), while _delta_log keeps commit history for 30 days. The old version still resolves but its files are gone, so the read fails.

open as a page

Why does a Delta Lake MERGE INTO fail when the source contains duplicate keys?

level: middleimportance: should knowfreq 58%
basics
~20 s

A matched UPDATE or DELETE must have a single, deterministic outcome per target row. If two source rows match the same target row, Delta cannot decide which wins and aborts the merge. The fix is to deduplicate the source to one row per key.

open as a page