Expert Track · Phase J · 16 of 26
Beyond streaming and OLAP — the lakehouse converges cheap object storage with ACID transactions + time travel + multi-engine compatibility.
Module 62 · Expert 16 / 26 · 90 min

Data lakehouse
architectures.

The specific engineering that turns "our data is scattered across a proprietary warehouse and a raw S3 dump" into "we have one open-format lakehouse queryable by any engine, with ACID transactions, time travel to any historical snapshot, and schema evolution without rewriting a byte." Apache Iceberg — snapshot-based transactions, hidden partitioning, format-agnostic, now the dominant format. Delta Lake — transaction log approach, tight Databricks integration, converging with Iceberg via Uniform. Apache Hudi — optimized for upsert-heavy CDC workloads, record-level indexing, copy-on-write vs merge-on-read. Understanding these table formats — and how they compose with Trino, Spark, DuckDB, Snowflake, ClickHouse, and Athena for multi-engine query — is Expert-tier competence for modern data platforms.

// What you\'ll know by the end

  • Table format internals (metadata, snapshots, manifests)
  • Iceberg vs Delta Lake vs Hudi trade-offs
  • Hidden partitioning + schema evolution + time travel
  • Multi-engine query (Trino, Spark, DuckDB, Snowflake, CH)
§ 01 — Why the lakehouse became inevitable

One storage layer.
Six query engines.
ACID + time travel
on S3.

The lakehouse is the convergence of two previously separate architectures: cheap object-storage data lakes (raw Parquet files on S3/GCS/Azure Blob) and expensive proprietary analytical warehouses (Snowflake, BigQuery, Redshift). For a decade (2010-2020), these were a stark either-or: lakes gave you cheap storage + open formats + no ACID + no time travel + poor query performance; warehouses gave you ACID + fast query + closed formats + expensive storage + vendor lock-in. Netflix ran petabyte-scale analytics on raw Parquet in S3 and hit specific pain points every day — concurrent writers corrupting each other, no way to atomically update a table, no way to query "the state of this table 3 days ago," schema evolution requiring full rewrites, partition pruning that required users to know the partition scheme by heart. In 2016, Ryan Blue at Netflix started building what became Apache Iceberg to solve these problems. In parallel, Databricks built Delta Lake internally (open-sourced 2019); Uber built Hudi for their upsert-heavy CDC pipelines (2016-2019). By 2024, the industry had converged: table formats are how you build modern analytical infrastructure. Snowflake supports Iceberg as external tables (announced 2022, GA 2023). Databricks — Delta Lake\'s creator — acquired Iceberg company Tabular in 2024 for $2B and released Uniform to make Delta ↔ Iceberg interoperable. AWS launched S3 Tables (Iceberg-native storage tier) in 2024. Query engines — Trino, Spark, DuckDB, ClickHouse, Athena, Flink — all speak Iceberg (and increasingly Delta). The specific engineering task: choose a table format, choose query engines, compose them into a lakehouse that gives you cheap S3 storage + ACID transactions + time travel + schema evolution + multi-engine access. Understanding this composition is Expert-tier competence for modern data infrastructure — because every mature data platform is (or is becoming) a lakehouse.

// LAKEHOUSE ARCHITECTURE · TABLE FORMAT UNIFIES LAKE + WAREHOUSE
LAKEHOUSE ARCHITECTURE · OPEN FORMAT · MULTI-ENGINE · ACID + TIME TRAVEL QUERY ENGINES · read/write same tables Trino distributed SQL Spark batch + ML DuckDB embedded OLAP Snowflake external tables ClickHouse analytical Athena serverless SQL TABLE FORMAT · METADATA LAYER · ACID + SNAPSHOTS + SCHEMA Apache Iceberg · Delta Lake · Apache Hudi ✓ ACID transactions (snapshot isolation) ✓ Time travel to any historical snapshot ✓ Schema evolution (add/rename/drop cols) ✓ Hidden partitioning + partition pruning DATA FILES · COLUMNAR PARQUET · OBJECT STORAGE S3 · GCS · Azure Blob · MinIO · thousands of Parquet files per table events-01.parquet events-02.parquet events-03.parquet events-04.parquet ... CATALOG (metadata coordinator) → AWS Glue · Nessie · Polaris · Unity → tracks current snapshot per table → atomic pointer swap = ACID commit CAPABILITIES vs raw Parquet → concurrent writes without corruption → SELECT ... FOR VERSION AS OF ... → ALTER TABLE ADD COLUMN (no rewrite)
The lakehouse architecture is layered: at the bottom, thousands of Parquet files on cheap object storage; a table format metadata layer above adds ACID transactions, snapshots, and schema evolution; query engines above read/write through the metadata layer. Data layer: columnar Parquet files (typically 128MB-1GB each) sitting in S3/GCS/Azure Blob/MinIO. Storage cost pennies per GB per month vs Snowflake\'s $23-40/TB/month effective rate (compute is separate). Parquet gives you columnar compression (typically 5-15× vs raw), column pruning (read only needed columns), predicate pushdown (filter at file level via min/max stats). But raw Parquet lacks: ACID, time travel, atomic multi-file updates, schema evolution without rewriting, hidden partitioning. Table format layer (Apache Iceberg / Delta Lake / Apache Hudi): a metadata layer that turns a directory of Parquet files into a proper table. Each write creates a new snapshot (immutable manifest listing all data files in the table at that point in time); commit = atomic pointer swap in the catalog from old snapshot to new. Snapshot isolation for readers (they see a consistent snapshot even during concurrent writes). Time travel: query any historical snapshot via SELECT ... FOR VERSION AS OF snap_id or FOR TIMESTAMP AS OF ts. Schema evolution: add/rename/drop columns via metadata-only operation; existing files unchanged; readers use the current schema to interpret older files. Hidden partitioning (Iceberg innovation): partition transforms like bucket(user_id, 128) or day(ts) are recorded in table metadata; users write WHERE ts BETWEEN ... and get automatic partition pruning without knowing the physical partition scheme. Query engines: Trino (distributed SQL, industry-standard for lakehouse queries), Spark (batch + ML), DuckDB (embedded analytical, exploding in popularity), Snowflake (external table support since 2023), ClickHouse (native Iceberg since 2024), Amazon Athena (serverless SQL, Iceberg-native), Amazon Redshift, Databricks, StarRocks, Doris. Any engine can read Iceberg tables; increasingly any engine can write. Key insight: your data is not locked to a specific engine anymore. Catalog: metadata coordinator that tracks "which snapshot is current for each table." Options: AWS Glue (managed, AWS-integrated), Nessie (git-like branching for data), Polaris (Snowflake\'s open catalog, 2024), Unity Catalog (Databricks, going open-source), Hive Metastore (legacy, still widely used). Catalog choice affects governance + tooling + which engines can natively use tables.

The specific engineering task M.62 addresses is understanding how table formats work internally (metadata, manifests, snapshots), how they differ (Iceberg vs Delta vs Hudi), and how to compose them with query engines (Trino, Spark, DuckDB, Snowflake, ClickHouse) into a real lakehouse. The critical insight: table formats are not just "Parquet plus metadata." They\'re the architectural primitive that unifies analytical infrastructure. Modern lakehouses have four properties: (a) Open format — Parquet (data) + open table format (metadata) means your data is not locked to any single engine. Migrating from Snowflake to Trino, or adding DuckDB for local analytics, doesn\'t require data migration — just a new engine reading the same tables. (b) ACID transactions — snapshot isolation for readers, atomic commits for writers, no partial updates visible. Concurrent writers coordinated via catalog (Iceberg\'s optimistic concurrency; Delta\'s transaction log). Standard database semantics on cheap storage. (c) Time travel — query any historical snapshot. Reproducibility for ML training runs; audit for compliance; recovery from bad writes (ROLLBACK TO ...). (d) Schema evolution — add/rename/drop columns via metadata-only operation; existing files unchanged; readers interpret older files via current schema. Enables agility without rewriting terabytes. Each of the three table formats implements these properties with different trade-offs: Iceberg optimizes for open multi-engine access + hidden partitioning; Delta Lake optimizes for Databricks integration + streaming writes; Hudi optimizes for upsert-heavy CDC workloads. Understanding when each fits is Expert-tier competence.

// FOUR APPROACHES TO ANALYTICAL STORAGE · WHERE EACH FAILS OR FITS
Attempt 1: Snowflake / BigQuery / Redshift (proprietary warehouse)// fast query · expensive · vendor lock-in
"Just use Snowflake. It\'s fast, it\'s SQL, it\'s ACID. Pay the bill." Works well for many use cases: excellent query performance, mature SQL, ACID transactions, time travel, zero ops for the storage engine. But specific limits: (a) VENDOR LOCK-IN — data lives in proprietary storage format (Snowflake\'s FDN, BigQuery\'s Capacitor, Redshift\'s columnar). Cannot query with any other engine without exporting. Migration is a project. (b) COST AT SCALE — storage $23-40/TB/month effective (10× S3 direct); compute $2-4/credit or per-slot-hour. At 10PB scale, total cost can hit $100K-1M/month. Multi-cloud deployment doubles this. (c) NO MULTI-ENGINE — need ML on the same data? Extract to files first. Need to run a DuckDB local query? Extract first. Every engine change = data pipeline. (d) TIGHT COUPLING — storage + compute + query engine + catalog + governance all in one proprietary system. Cannot swap components. Fine for many workloads; wrong when open format + multi-engine access + cost economics matter. Increasingly, mature companies move away from warehouse-only architectures toward lakehouse (or hybrid: warehouse for hot + lakehouse for cold).// FAIL MODE: vendor lock-in · $$$ at scale · no multi-engine · tight coupling
LOCKED-IN
EXPENSIVE
Attempt 2: Raw Parquet on S3 + Hive Metastore// cheap storage · no ACID · corruption risk
"Just dump Parquet files to S3. Use Hive Metastore to track partitions. Query with Presto/Trino/Athena. Cheap and open." The 2015-2019 data lake pattern. Storage costs pennies. Multi-engine query works (Presto, Athena, Spark, Hive). But specific failure modes: (a) NO ACID — concurrent writers can corrupt each other. Reader might see partial writes (files present but not all data files for a "logical update"). No atomic multi-file operations. (b) NO TIME TRAVEL — deleted files are gone. No way to recover from a bad write. No way to reproduce yesterday\'s query result. (c) SCHEMA EVOLUTION IS PAINFUL — Hive\'s schema-on-read means adding a column requires rewriting all files (to update schema in file footers) or accepting inconsistent files across the table. Rename column = rewrite everything. (d) PARTITION PRUNING VIA CONVENTION — users must know partition columns and write queries like WHERE date=\'2024-01-15\'. Mismatch on convention = full-table scan on petabytes. Everyone\'s hit this. (e) SMALL FILES PROBLEM — many small Parquet files (from streaming ingestion) destroy query performance. No automatic compaction. Standard failure. Netflix hit all of these at petabyte scale — which is why they built Iceberg. This is the pattern lakehouses replaced.// FAIL MODE: no ACID · no time travel · painful schema evolution · corruption risk
CORRUPTION
PRONE
Attempt 3: Hive-style ACID / Hadoop-era transactions// technically ACID · operationally awful · legacy
"Hive has ACID support — enable it. Or use Hudi COW tables on HDFS with a Hive Metastore. Legacy but proven." Hive did add ACID support (Hive 0.13+, 2014) via delta files + compaction; technically works but was designed for HDFS + MapReduce era. Specific limits: (a) HDFS ASSUMPTION — Hive ACID + Hadoop-era transactions assume HDFS semantics (fast rename operations for atomic swaps). Object storage (S3) has no fast rename — rename = copy + delete, expensive + non-atomic. Hive ACID on S3 is notoriously slow and error-prone. (b) DELTA FILE PROLIFERATION — writes create delta files; queries merge base + deltas at read time. Without frequent compaction, queries slow linearly with delta count. Operational nightmare. (c) LIMITED ENGINE SUPPORT — Hive ACID works well with Hive + Impala; other engines have partial or no support. Multi-engine access broken. (d) COMPLEX METASTORE — Hive Metastore is a critical single point that\'s hard to scale + operate. Legacy Java + relational DB backend. Netflix + others explicitly moved off it. Standard "we tried enterprise Hadoop-era ACID" story: works in theory, painful in practice, superseded by modern table formats (Iceberg / Delta / Hudi) that were designed for object storage from day one.// FAIL MODE: HDFS assumptions · slow on S3 · limited engines · legacy Hadoop
TECHNICALLY
ACID
Attempt 4: Modern lakehouse · Iceberg / Delta / Hudi + multi-engine// open · ACID · time travel · multi-engine · modern production
"Use Apache Iceberg (or Delta Lake or Hudi) as the table format on S3. Compose with Trino for SQL, Spark for ML, DuckDB for local exploration, and Snowflake/ClickHouse for specific query engines. Catalog via AWS Glue, Nessie, Polaris, or Unity." The specific modern engineering. Specifically: (a) Apache Iceberg: snapshot-based transactions; each snapshot is an immutable manifest list pointing to manifest files, which point to data files. Commit = atomic pointer swap in catalog. Hidden partitioning via partition transforms (bucket(user_id, 128), day(ts)). Format-agnostic (Parquet/ORC/Avro). Schema evolution: assign each column a stable ID; add/rename/drop columns via metadata only. Broad ecosystem: Trino, Spark, Flink, Snowflake, ClickHouse, Athena, Redshift, Doris, StarRocks all native. Dominant format 2023+. (b) Delta Lake: transaction log approach — _delta_log/ directory contains JSON files describing each commit (add/remove file operations). Commit = atomic append to log. Deeply integrated with Databricks/Spark. Delta 3.0 added Uniform (write once, read as Iceberg or Delta) — convergence with Iceberg. (c) Apache Hudi: designed for upsert-heavy workloads (CDC). Two table types: Copy-on-Write (COW — rewrite files on update, read-optimized) and Merge-on-Read (MOR — write delta files, merge at query, write-optimized). Record-level indexing for fast upserts. Popular at Uber, Robinhood. (d) Query engines: Trino as distributed SQL default (Iceberg-native); Spark for batch + ML; DuckDB for local exploration (SELECT * FROM iceberg_scan(\'s3://...\')); Snowflake for external table access; ClickHouse for analytical scale; Athena for serverless. Multi-engine on the same tables. (e) Catalog: AWS Glue (managed, AWS-native), Nessie (git-like branching), Polaris (Snowflake open, 2024), Unity (Databricks). Choice affects governance + tooling + engine compatibility. Standard modern data platform composition.// FIT: open format + ACID + time travel + multi-engine · production modern
PRODUCTION
MODERN
// THE COMPOSITE PATTERN

Each earlier attempt fails specifically. Snowflake/BigQuery lock you in and get expensive. Raw Parquet + Hive Metastore has corruption + no time travel + painful schema. Hive-era ACID assumes HDFS + doesn\'t compose with modern engines. The Expert pattern: modern table format (Iceberg dominant, Delta for Databricks-heavy shops, Hudi for CDC-heavy) on cheap object storage + multi-engine query (Trino, Spark, DuckDB, Snowflake, ClickHouse, Athena as needed) + catalog choice (AWS Glue, Nessie, Polaris, Unity) matched to governance needs. Understanding this composition is Expert-tier competence for modern data platforms. §02 covers table format internals (metadata, snapshots, manifests). §03 covers three formats + query engines. §04 lets you explore all three formats across three use cases.

The historical arc of the lakehouse is specifically the story of how open table formats displaced both proprietary warehouses and primitive data lakes. 2009: Hadoop HDFS + Hive. Yahoo + Facebook — SQL over HDFS with schema-on-read via Hive Metastore. Foundational but crude. 2010: Parquet. Twitter + Cloudera — columnar file format optimized for analytical queries. Column pruning, predicate pushdown, compression. Standard for lakes 2013+. 2013: Presto. Facebook — distributed SQL over Hive Metastore + S3 Parquet. Renamed Trino in 2020 after governance dispute. 2015: Databricks Delta (internal). Databricks building ACID + time travel on Spark for their customers. Not open. 2016: Iceberg (internal at Netflix). Ryan Blue at Netflix, frustrated with Hive Metastore limits + partition pruning bugs, starts building Iceberg. 2016: Hudi (internal at Uber). Vinoth Chandar building CDC-optimized table format at Uber for their high-upsert workloads. 2019: Delta Lake open-sourced (0.1). Databricks strategic move to popularize their table format. 2019: Iceberg becomes Apache project. Netflix contributes to Apache. 2019: Hudi becomes Apache project. Uber contributes to Apache. Three formats now open-source and competing. 2020: Trino renamed from PrestoSQL. After governance dispute with Facebook, PrestoSQL becomes Trino. Continues as primary distributed SQL engine for lakehouse. 2020: Iceberg 0.11 with hidden partitioning. Killer feature — users query without knowing partition scheme. Adoption accelerates. 2020: DuckDB emerges. Hannes Mühleisen + Mark Raasveldt — embedded analytical database. By 2023, native Iceberg + Delta support. Becomes standard for local exploration of lakehouse data. 2021: Kafka Tiered Storage (KIP-405). Streaming pipelines can offload old data to S3 in Parquet, integrating with lakehouses. 2022: Snowflake announces Iceberg external tables. Even proprietary warehouses adopt Iceberg for external data. 2023: Iceberg wins mindshare. Trino, Spark, Snowflake, ClickHouse, Athena all Iceberg-native. Delta 3.0 releases Uniform (Delta ↔ Iceberg interop). 2024: Databricks acquires Tabular for $2B. Tabular = commercial Iceberg company founded by Netflix\'s Ryan Blue. Databricks — Delta\'s creator — acquiring Iceberg\'s commercial arm signals convergence. Uniform becomes the compatibility layer. 2024: AWS S3 Tables. AWS launches Iceberg-native storage tier — S3 becomes a first-class lakehouse platform. 2024: Polaris Catalog (Snowflake open). Snowflake open-sources their catalog implementation. 2024: Unity Catalog (Databricks going open). Databricks announces Unity Catalog will be fully open-source. Catalog wars end via convergence. 2025: Iceberg is the universal analytical table format. Every serious analytical engine supports it; every serious data platform uses it. The historical arc explains why lakehouse became inevitable — the pressures against warehouse lock-in and lake primitiveness both pointed toward open table formats, and Iceberg won by being genuinely open + engine-neutral + technically excellent (hidden partitioning is the killer feature).

The lakehouse turns "cheap S3 storage" into "ACID transactional analytical infrastructure" via a metadata layer. Iceberg won. Delta converged. Hudi specialized. Trino, Spark, DuckDB, Snowflake all read the same tables. This is the modern data platform.
§ 02 — Table format internals · metadata · snapshots · manifests

Metadata over
Parquet.
ACID via atomic
pointer swap.

Modern table formats add a metadata layer over Parquet files that transforms a directory of files into a proper ACID-transactional table. The specific engineering: each write creates a new immutable snapshot (a description of "which data files exist in this table right now"); the catalog holds a pointer to the current snapshot; commit = atomic pointer swap from old snapshot to new. Readers grab the current snapshot at query start; concurrent writers create new snapshots in parallel; conflicts resolved via optimistic concurrency (retry with updated base). Time travel: keep old snapshots for N days; query any historical snapshot by ID or timestamp. Schema evolution: schema stored in metadata with stable column IDs; add/rename/drop columns by editing metadata only; readers apply current schema when interpreting old Parquet files. Understanding these mechanics — snapshot semantics, manifest structure, atomic commit protocols — is Expert-tier competence because it explains everything about how table formats deliver their capabilities.

// ICEBERG TABLE INTERNALS · CATALOG → SNAPSHOT → MANIFESTS → DATA FILES

ICEBERG TABLE · METADATA HIERARCHY · ATOMIC COMMIT CATALOG (AWS Glue / Nessie / Polaris / Unity) table: sales.transactions → current_metadata: s3://.../metadata/v42.metadata.json TABLE METADATA FILE · v42.metadata.json schema (with column IDs) · partition spec · snapshots list · current-snapshot-id: snap-8f2c properties (compression, target file size, etc.) · sort orders · snapshot log (history) SNAPSHOT snap-8f2c · manifest-list-8f2c.avro timestamp · parent-snapshot: snap-7a1b · operation: append · summary (added-records, total-records) list of manifest files (each covers a subset of data files; partition min/max stats) MANIFEST FILES · manifest-*.avro (per partition or per commit) manifest-A.avro files: [file-01.pq, file-02.pq] partition: day=2024-01-15 manifest-B.avro files: [file-03.pq, file-04.pq] partition: day=2024-01-16 manifest-C.avro files: [file-05.pq, file-06.pq] partition: day=2024-01-17 DATA FILES · Parquet columnar · min/max stats per column per file file-01.parquet 128 MB file-02.parquet 128 MB file-03.parquet 128 MB file-04.parquet 128 MB file-05.parquet 128 MB file-06.parquet 128 MB commit = atomic pointer update in catalog: v42.metadata.json → v43.metadata.json
The specific Iceberg table format architecture. Catalog: holds a pointer per table to the current metadata file. Options: AWS Glue (managed), Nessie (git-like), Polaris (Snowflake), Unity (Databricks), Hive Metastore (legacy). Catalog operations must be atomic — that\'s what makes ACID commits possible. Iceberg supports multiple catalog implementations via a plugin interface. Table metadata file (JSON, versioned like v42.metadata.json): contains the current schema (with stable column IDs, not names — critical for schema evolution), partition specification (which columns partitioned by which transform), list of all snapshots, the current-snapshot ID, table properties (compression, target file size, format version), sort orders. Each schema/partition/snapshot change bumps the version number. Metadata files are immutable; each commit writes a new metadata file. Snapshot: an immutable description of "which data files exist in this table at this point in time." Stored as a manifest-list file (Avro format). Contains: timestamp, parent snapshot ID (for lineage), operation type (append/overwrite/replace/delete), summary statistics (added-records, deleted-records, total-records, total-data-files), list of manifest files. Snapshots form a lineage tree (parent pointers). Manifest files (Avro, typically one per partition or per commit): each manifest lists a subset of data files with per-file metadata: file path, file size, record count, partition tuple, column-level min/max statistics (for predicate pushdown), null counts, distinct value counts. Multi-level design — snapshot has list of manifests, manifests have lists of data files — enables efficient partial reads (query planner only reads manifests for relevant partitions). Data files: Parquet (or ORC or Avro) files sitting in object storage. Immutable. Each file typically 128MB-1GB (target size configurable). Contains actual data with column-level min/max stats stored in Parquet footer. The commit protocol: (i) writer prepares new data files (writes Parquet to S3); (ii) writer creates new manifest files describing them; (iii) writer creates new manifest-list (snapshot) file; (iv) writer creates new metadata file (v42 → v43) pointing to new snapshot; (v) writer performs atomic swap in catalog: update table.current_metadata from v42.metadata.json to v43.metadata.json. Step (v) is the atomic commit — one atomic catalog operation (typically a compare-and-swap in AWS Glue, or a Git-like commit in Nessie). Before the swap, readers see v42 (old snapshot); after, they see v43 (new snapshot). No partial state ever visible. This is snapshot isolation. Concurrent writers: two writers might both try to commit v42 → v43. Only one succeeds (the CAS wins); the loser retries, reads v43 as new base, and creates v44. Standard optimistic concurrency. Understanding this hierarchy — catalog → metadata → snapshot → manifest → data — is Expert-tier competence, because it explains how Iceberg delivers ACID + time travel + hidden partitioning + schema evolution.
i
Snapshot semantics.

Every write creates immutable snapshot. Readers see consistent snapshot at query start. Time travel = query any historical snapshot by ID or timestamp. Snapshot expiration cleans up old ones. Foundation of all lakehouse ACID.

ii
Manifest hierarchy.

Snapshot → manifest list → manifests → data files. Multi-level enables efficient partial reads via metadata pruning. Manifests cache min/max stats per file — predicate pushdown at planning time. Standard scalable metadata design.

iii
Atomic pointer swap.

Commit = CAS in catalog updating current metadata pointer. Guarantees atomicity across many data files. Concurrent writers via optimistic concurrency (retry on conflict). Standard modern ACID over object storage.

iv
Hidden partitioning.

Iceberg innovation: partition transforms (bucket(user_id, 128), day(ts)) recorded in metadata. Users write WHERE ts BETWEEN ... — engine applies transform + prunes partitions automatically. No convention-based magic.

v
Schema evolution via IDs.

Columns identified by stable IDs (not names) in metadata + Parquet. Add column: new ID, metadata-only. Rename column: change name in metadata, keep ID. Drop column: mark deleted in metadata, physical files unchanged. Metadata-only ops on petabyte tables.

vi
Compaction + snapshot expiry.

Small-files compaction merges many small Parquet files into fewer large ones. Snapshot expiry deletes old snapshots + orphaned files past retention. Both are maintenance operations that keep the table healthy. Without them: metadata bloat + query slowdown.

The hidden partitioning innovation (mech item iv) deserves specific attention because it\'s the killer feature that made Iceberg dominant. Consider the pain point in Hive-era data lakes: to get partition pruning on a date-partitioned table, users had to know the partition column and write queries like WHERE date_partition=\'2024-01-15\' AND ts BETWEEN \'2024-01-15T09:00:00\' AND \'2024-01-15T10:00:00\'. The date_partition= predicate was essential for pruning — without it, the query would scan every day\'s data. But this couples query authors to physical storage layout. Change from daily partitions to hourly? All queries break. Rename partition column? Same. Users constantly wrote broken queries that missed pruning and cost $100s in Snowflake credits. Iceberg\'s fix: partition transforms are declared in table metadata (PARTITIONED BY (day(ts), bucket(user_id, 128))). Users write queries against logical columns only: WHERE ts BETWEEN \'2024-01-15T09:00:00\' AND \'2024-01-15T10:00:00\' AND user_id = 12345. The Iceberg engine automatically: (a) applies the day() transform to the timestamp range → identifies matching day partitions; (b) applies bucket(user_id, 128) → identifies matching bucket; (c) uses manifest min/max stats to prune further. Users never see the partition scheme. Change from daily to hourly: metadata-only change (ALTER TABLE ... REPLACE PARTITION FIELD day(ts) WITH hour(ts)); existing queries continue working; new writes use new partitioning. This eliminates an entire category of production bugs and enables partition strategy evolution without breaking queries. Standard reason teams choose Iceberg over Delta or Hudi.

The schema evolution via stable column IDs (mech item v) is the other Iceberg innovation. Consider the pain point in raw Parquet lakes: to add a column, you either (a) rewrite all Parquet files (petabyte-scale rewrite); (b) accept that old files lack the column (readers must handle null); (c) rename column by rewriting everything. Renames were especially painful. Iceberg\'s fix: each column has a stable integer ID assigned at creation. The metadata maps ID → current name; Parquet files store data by ID. Add column: assign new ID, add to schema, metadata-only. Rename: change the name in schema for the ID; existing Parquet files unchanged (they use ID). Drop: remove name from schema, but ID stays reserved (never reused); old files can still be read for time travel. Old file with columns [1, 2, 3] read after column 3 renamed and column 4 added: engine looks up IDs 1, 2, 3, 4 in current schema; file has 1, 2, 3 with data + 4 missing (null); engine returns rows with current names for all four columns. Zero rewrites, works with time travel, safe. Delta Lake achieves similar via column mapping (added in 2022); Hudi has schema evolution too but historically less mature. Understanding these mechanisms is Expert-tier competence for building agile analytical infrastructure — because "add a column to a petabyte table without downtime" turns out to matter a lot.

Snapshots for ACID. Manifests for pruning. Column IDs for schema evolution. Partition transforms for hidden partitioning. Atomic pointer swap for commit. These are the primitives. Every lakehouse feature emerges from them.
§ 03 — Three formats + query engines · Iceberg / Delta Lake / Hudi · Trino / Spark / DuckDB / Snowflake / ClickHouse

Iceberg. Delta.
Hudi.
All read by
Trino, Spark,
DuckDB, Snowflake.

Modern lakehouse infrastructure has three canonical table formats + multi-engine query, each with specific fits. Table formats: (a) Apache Iceberg — Netflix origin (2016), Apache since 2019, snapshot-based transactions, hidden partitioning, format-agnostic (Parquet/ORC/Avro), broad multi-engine support. Dominant format 2023+. (b) Delta Lake — Databricks origin (2016 internal, 2019 open), transaction log approach, tight Databricks/Spark integration, Delta 3.0 added Uniform (Delta ↔ Iceberg interop), 2024 Databricks acquired Iceberg company Tabular signaling convergence. (c) Apache Hudi — Uber origin (2016), Apache since 2019, designed for upsert-heavy CDC workloads, record-level indexing, Copy-on-Write (COW, read-optimized) vs Merge-on-Read (MOR, write-optimized) tables. Popular at Uber, Robinhood, ByteDance for CDC scenarios. Query engines: (i) Trino — distributed SQL, industry-standard for lakehouse; started as PrestoSQL, renamed 2020; excellent Iceberg support, growing Delta support. (ii) Spark — batch + ML processing; native Delta support (Databricks); strong Iceberg support. (iii) DuckDB — embedded analytical database; native Iceberg + Delta support; exploding in popularity for local exploration + notebooks. (iv) Snowflake — external table support for Iceberg (2023 GA); Delta support (2024); still primary storage in proprietary format but reading Iceberg tables from S3 works. (v) ClickHouse — native Iceberg (2024); great for analytical time-series over lakehouse. (vi) Athena — AWS serverless SQL; Iceberg-native. (vii) Databricks (Photon) — Delta primary, Iceberg via Uniform. Understanding when each fits — and how they compose — is Expert-tier competence because modern lakehouses run 4-8 different query engines on the same tables for different workload characteristics.

// ICEBERG · DELTA LAKE · HUDI · SIDE-BY-SIDE

THREE TABLE FORMATS · ARCHITECTURAL COMPARISON APACHE ICEBERG Netflix origin · dominant 2023+ METADATA: Snapshot-based hierarchy manifest-list → manifests Catalog: Glue/Nessie/Polaris KILLER FEATURES: Hidden partitioning (unique) Format-agnostic (Parquet/ORC) Schema evolution by ID ENGINE SUPPORT: Trino · Spark · Flink DuckDB · Snowflake · Athena ClickHouse · Doris · StarRocks FITS: ✓ Multi-engine (broadest) ✓ Open-format priority ✓ Cloud-agnostic ✗ Streaming less mature (improving) DELTA LAKE Databricks origin · Uniform ↔ Iceberg METADATA: Transaction log approach _delta_log/ JSON files Unity Catalog (going open) KILLER FEATURES: Deep Spark/Databricks integ. Streaming reads/writes native Uniform (read as Iceberg too) ENGINE SUPPORT: Spark (best) · Databricks Trino (growing) · DuckDB Snowflake (via Uniform 2024) FITS: ✓ Databricks-heavy shops ✓ Streaming from day one ✓ Spark-first workloads ✗ Multi-engine narrower than Iceberg APACHE HUDI Uber origin · CDC-optimized METADATA: Timeline of commits Record-level indexing .hoodie/ directory KILLER FEATURES: Upsert-optimized (record idx) COW vs MOR table types Incremental queries ENGINE SUPPORT: Spark · Flink · Presto Trino (basic) Hive (legacy Hadoop) FITS: ✓ Upsert-heavy CDC pipelines ✓ MOR for write-heavy ✓ Incremental consumers ✗ Narrower engine support
The three modern table formats each optimize different aspects of the lakehouse problem. Apache Iceberg: snapshot-based hierarchy (metadata → snapshot → manifest list → manifests → data files); killer features are hidden partitioning (partition transforms recorded in metadata; users query logical columns; engine applies transforms and prunes automatically) and format-agnostic design (Parquet/ORC/Avro all supported); schema evolution via stable column IDs; catalog-agnostic (AWS Glue, Nessie, Polaris, Unity, Hive Metastore). Broadest multi-engine support: Trino, Spark, Flink, DuckDB, Snowflake, ClickHouse, Athena, Doris, StarRocks, Redshift Spectrum all read natively. Best choice for open-format-priority + multi-engine + cloud-agnostic architectures. Dominant format 2023+. Delta Lake: transaction log approach — each commit is a JSON file in _delta_log/ directory describing add/remove file operations; log becomes the source of truth; deep Spark/Databricks integration (Databricks Photon engine is Delta-native). Killer features: mature streaming reads/writes (Delta Streaming, Structured Streaming integration); Uniform (Delta 3.0, 2023) writes Delta but the same files can be read as Iceberg — enables coexistence. Unity Catalog (Databricks, going open-source 2024) provides governance. Best choice for Databricks-heavy shops, Spark-first workloads, streaming-heavy pipelines. Apache Hudi: timeline of commits + record-level indexing; two table types — Copy-on-Write (COW) rewrites entire files on update (read-optimized, slow writes) and Merge-on-Read (MOR) writes delta files that merge with base at query time (fast writes, slower reads until compaction). Killer features: upsert-optimized with record-level indexing (fast merge of CDC updates); incremental queries (SELECT * FROM table WHERE commit_time > last_processed — CDC-style consumption from Hudi tables). Popular at Uber, Robinhood, ByteDance for CDC scenarios. Best choice when the workload is dominated by upserts/CDC and read-write balance matters. Choosing among the three: MULTI-ENGINE PRIORITY → Iceberg (broadest support, open governance, format-agnostic). DATABRICKS-HEAVY → Delta (native integration, best Spark performance, Uniform for read-only compatibility). CDC-HEAVY UPSERT WORKLOADS → Hudi (record-level indexing, MOR for write-heavy). Since 2024, the industry is converging on Iceberg for most new deployments; Delta continues where Databricks is central; Hudi remains best for CDC-heavy specialized workloads.
i
Apache Iceberg.

Netflix origin. Snapshot-based, format-agnostic, hidden partitioning, schema evolution via IDs. Broadest multi-engine support. Dominant format 2023+. Standard choice for new lakehouse deployments.

ii
Delta Lake.

Databricks origin. Transaction log in _delta_log/. Deep Databricks/Spark integration. Uniform (2023) enables read-as-Iceberg for interop. Best for Databricks-heavy shops + streaming workloads.

iii
Apache Hudi.

Uber origin. Record-level indexing for fast upserts. COW (read-optimized) vs MOR (write-optimized) table types. Incremental queries for CDC consumption. Popular at Uber, Robinhood. Best for upsert-heavy CDC pipelines.

iv
Trino + Spark.

Trino: distributed SQL, industry-standard interactive query for lakehouse. Spark: batch + ML processing, native Delta, strong Iceberg. Both scale to petabyte queries. Foundation of modern lakehouse query layer.

v
DuckDB + Snowflake.

DuckDB: embedded analytical DB; native Iceberg + Delta; exploded in popularity 2023+ for local exploration + notebooks + edge analytics. Snowflake: added Iceberg external tables (2023) + Delta via Uniform (2024). Even proprietary warehouses adopt lakehouse.

vi
ClickHouse + Athena.

ClickHouse: native Iceberg (2024) — analytical-scale queries over lakehouse. Athena: AWS serverless SQL, Iceberg-native, deep S3 integration. Both excellent for specific workloads composed alongside Trino/Spark on the same tables.

The Iceberg-Delta convergence (mech items i+ii) is the defining trend of 2023-2025 lakehouse evolution. Historically, Iceberg and Delta competed: Iceberg with Netflix + open governance + broad engine support; Delta with Databricks + closed governance + tight Spark integration. By 2024, the convergence accelerated: (a) Databricks acquires Tabular for $2B (June 2024) — Tabular was the commercial Iceberg company founded by Netflix\'s Ryan Blue (Iceberg\'s creator) and Dan Weeks. Databricks — Delta\'s creator — acquiring Iceberg\'s commercial arm signals that they see Iceberg as strategic, not competitive. (b) Delta Uniform — Delta 3.0 (2023) added Uniform: write Delta, and the same files can be read as Iceberg tables. Enables Delta writers + Iceberg readers coexistence. Databricks explicitly positioned this as "one format from two perspectives." (c) Snowflake Polaris Catalog (2024) — Snowflake open-sourced their Iceberg catalog implementation. Even a warehouse vendor embracing Iceberg as the open storage layer. (d) Unity Catalog going open (Databricks announced 2024) — Databricks open-sourcing their catalog, which supports both Delta and Iceberg. The industry has decided: Iceberg is the format; Delta is a specific implementation; both should interop. For most new deployments in 2025, choose Iceberg. Continue Delta if Databricks-heavy. Understand both because they\'re increasingly interop-able. Standard modern lakehouse discipline.

The Trino + Spark + DuckDB triad (mech items iv+v) forms the query layer of modern lakehouses. Each has specific fit: (a) Trino — distributed SQL engine, designed for interactive analytical queries over external data (S3, HDFS, RDBMS, lakehouse). Started as PrestoSQL at Facebook (2012); forked and renamed Trino in 2020 after governance disputes. Extensive connector ecosystem — reads from Iceberg (best), Delta, Hudi (basic), Postgres, MySQL, Elasticsearch, Cassandra, Kafka, and 40+ others. Federated queries across sources. Industry-standard for lakehouse interactive query at Netflix, LinkedIn, Airbnb, Shopify. Runs on cluster (typically 20-1000 nodes). Alternative: Presto (Facebook fork), StarRocks, Doris — but Trino has strongest lakehouse ecosystem. (b) Spark — batch processing + ML + streaming; primary compute engine for Databricks; excellent Delta support (native); good Iceberg support; strong Hudi support. Scales to enormous batch jobs. Foundation of ML pipelines (MLlib, Spark ML). Standard for ETL + ML feature engineering + batch analytics. (c) DuckDB — embedded analytical database (like SQLite for analytics); single-node, in-process, no server; native Iceberg + Delta support (2023+). Exploded in popularity 2023-2024 for: local data exploration on laptops (query S3 lakehouse tables from Jupyter notebook); edge analytics; embedding in applications; CI/CD data validation; interactive dashboards. Extremely fast on single node (SIMD, vectorization). Not distributed but often faster than Trino for gigabyte-scale queries. Standard modern data engineering tool. Composition pattern: Trino for interactive multi-user cluster queries; Spark for batch ETL + ML; DuckDB for local exploration + notebooks + small analytical workloads. All three on the same tables. Standard modern lakehouse.

The engine-agnostic composition is the fundamental architectural benefit of the lakehouse. Consider the historical alternative: your data lives in Snowflake, you need to run ML training in Databricks, so you export from Snowflake → S3 → import to Databricks → train → export result → import back to Snowflake. Data movement is slow (petabytes take hours), expensive (network + storage duplicate), and error-prone (schema drift, missing rows). With a lakehouse: your data lives as Iceberg tables in S3; Snowflake reads the same tables for BI; Databricks/Spark reads the same tables for ML training; DuckDB reads the same tables for local exploration; Trino reads for interactive queries; ClickHouse reads for time-series aggregations; Athena reads for serverless ad-hoc. Zero data movement between engines. Add a new engine (e.g., new team wants StarRocks): just point it at the same tables. Remove an engine (e.g., migrating off Snowflake): stop using it; data is safe. This composition — one storage layer, many query engines — is why the lakehouse became the modern default. Understanding how to architect for it is Expert-tier competence.

Iceberg for the open format. Delta for the Databricks integration. Hudi for the CDC upserts. Trino for interactive query. Spark for batch + ML. DuckDB for local. Snowflake, ClickHouse, Athena on the same tables. This is the lakehouse.
§ 04 — Lakehouse explorer

Three formats.
Three use cases.

Below: each of three table formats (Apache Iceberg · Delta Lake · Apache Hudi) evaluated against three canonical use cases (Batch analytical warehouse · Streaming CDC ingestion · Multi-engine query). Watch how each format fits or fails each use case — Iceberg dominates multi-engine and open-format-priority workloads, Delta excels for Databricks-heavy streaming, and Hudi wins on upsert-heavy CDC. The off-diagonals show where the wrong choice produces measurably worse ergonomics, engine support, or write throughput. The takeaway: match table format to workload; understand the convergence trend (Iceberg becoming universal) when picking for new deployments.

LAKEHOUSE.SIM // m.62 lab
Use case →
// LAKEHOUSE FLOW · under current use case
// METRICS · WRITE / QUERY / ACID / ENGINES / OPS / FIT
Write throughput-
Query latency-
ACID + time travel-
Engine support-
Ops complexity-
Overall fit-
// VERDICT
Loading...
...
§ 05 — Where lakehouses decay

Every regret is
raw Parquet,
small files, or
the wrong format.

The failure modes of lakehouse infrastructure are the specific mechanisms by which "our data lake works fine" turns into "queries take 3 hours and the last write corrupted the table." Each anti-pattern is a real production pattern; Expert engineers avoid them by using a proper table format, monitoring file sizes, choosing the right format for the workload, using hidden partitioning, and running maintenance jobs. Recognizing these saves months of "why is our lakehouse broken" debugging.

// FIVE LAKEHOUSE ANTI-PATTERNS

i
The raw Parquet without table format
"We dump Parquet files to S3 with a Hive Metastore tracking partitions. Query with Trino. Last week two ETL jobs ran concurrently and now the sales table is corrupted — some rows have wrong schema, some partitions are half-written."

Raw Parquet on S3 with Hive Metastore has no ACID guarantees. Concurrent writers can corrupt each other; readers see partial writes; there\'s no atomic way to update multiple files; no time travel to recover. Specifically: (a) NO ATOMIC MULTI-FILE OPERATIONS — a "logical update" that writes 100 Parquet files: if any subset succeeds and rest fail, readers see inconsistent state. Rolling back is manual + error-prone. (b) NO ISOLATION — writer replacing a partition while reader is scanning it: reader may see mix of old + new files. Standard failure. (c) NO TIME TRAVEL — if a bad write corrupts the table, no way to ROLLBACK TO .... Must restore from external backup (if you have one). (d) HIVE METASTORE LIMITATIONS — legacy Java + relational DB backend; hard to scale; assumes HDFS semantics (fast rename). Poor fit for S3. (e) SCHEMA EVOLUTION IS PAINFUL — add column = rewrite all files or accept inconsistent schema; rename column = rewrite everything. Petabyte-scale rewrites are days of runtime. The fix: (i) MIGRATE TO ICEBERG (or Delta or Hudi) — free of vendor cost; open source; catalog choices (AWS Glue, Nessie, Polaris, Unity). Migration typically week or two of engineering: (a) create Iceberg table pointing at existing Parquet directory (Iceberg supports "adopt existing data"); (b) update ETL to write via Iceberg (Trino/Spark/Flink handles this); (c) update readers to read Iceberg tables (mostly transparent — same SQL). (ii) IMMEDIATE BENEFITS: ACID commits (concurrent writers don\'t corrupt); snapshot isolation for readers; time travel (SELECT ... FOR VERSION AS OF ...); atomic partition replace; schema evolution via metadata; hidden partitioning eliminates query mistakes. (iii) COST: essentially zero if using self-hosted Iceberg on existing S3. Iceberg is Apache-licensed; catalog options include free (Hive Metastore, Nessie) or managed (AWS Glue at trivial cost). Standard modern discipline: table formats are baseline for any serious lakehouse. Raw Parquet + Hive Metastore is a 2015-2019 pattern superseded by table formats. Anti-pattern §05.i.

ii
The small files problem
"Our Iceberg table receives streaming writes every 30 seconds. After a few months we have 200,000 Parquet files averaging 5MB each. Simple queries that used to take 5 seconds now take 10 minutes. Trino spends most of the time opening files."

Streaming ingestion or small-batch writes create many small Parquet files. Query engines spend more time opening files (S3 request overhead, file metadata parsing) than reading data. The specific fix is compaction: periodically merge many small files into fewer large ones. Specifically: (a) THE MECHANISM. Every write creates new data files. Streaming ingestion writing 30-second batches creates a file every 30 seconds per partition = 2,880 files/day/partition. After 3 months: ~260K files. Each Parquet file has ~10-100ms open overhead on S3 (LIST + GET metadata + parse footer). Reading 260K files even with 100-way parallelism = 260ms just to open them. Actual data reading may take less than metadata parsing. Standard failure. (b) THE COMPACTION FIX. Run compaction jobs periodically: read many small files, sort optionally, write fewer large files (target 128MB-1GB each), commit as new snapshot. Iceberg rewrite_data_files procedure (Spark or Trino); Delta OPTIMIZE command; Hudi async compaction service. Different strategies: (i) BIN-PACKING — group small files by partition, write combined larger files. Simple. Standard. (ii) SORT-BASED — sort by frequently-queried columns during rewrite; enables better predicate pushdown. Slower but more benefit. (iii) Z-ORDER (Delta-native) — multi-dimensional sort optimizing for co-clustered access on multiple columns. (c) THE FREQUENCY DISCIPLINE. Compaction cadence depends on write pattern: (i) streaming ingest: hourly or 4-hourly compaction; keep hot partitions (last day) with small files, older partitions compacted. (ii) batch ingest: after each batch or nightly. (iii) automated in some engines (Delta Live Tables, Iceberg via async orchestration). (d) THE INGESTION-TIME MITIGATIONS. (i) BUFFERING — accumulate 30-second batches into 10-minute super-batches at ingest layer before writing to Iceberg. Fewer larger writes. (ii) TARGET FILE SIZE — set table property write.target-file-size-bytes to hint writers to buffer more before flushing. (iii) DEDICATED STREAMING FORMAT — for high-frequency streaming, Delta Live Tables or Hudi MOR handle small files better via delta files that compact separately. (e) THE FILE SIZE MONITORING. Track average file size + count per table via metadata queries (Iceberg files metadata table; Delta DESCRIBE DETAIL). Alert when avg file size drops below 32MB or file count grows > 100K per partition. Standard modern lakehouse ops. (f) THE MAINTENANCE JOB DISCIPLINE. Beyond compaction: (i) snapshot expiration (Iceberg expire_snapshots, Delta VACUUM) removes old snapshots + orphaned files past retention; (ii) manifest rewrite compacts manifest files themselves (metadata bloat is real); (iii) metadata stats refresh keeps min/max updated. Run these regularly (nightly typical). Anti-pattern §05.ii captures the entire small-files pathology.

iii
The not using hidden partitioning
"Our Iceberg table is partitioned by day(ts). Users write queries like WHERE ts BETWEEN '2024-01-15' AND '2024-01-16' and get 200GB scans instead of 2GB. They\'re asking why partition pruning isn\'t working."

Iceberg\'s hidden partitioning applies partition transforms automatically only if users query against the source column. But if users query against a Hive-era explicit partition column (that doesn\'t exist), pruning fails silently. Actually wait — this specific scenario shouldn\'t happen with proper Iceberg hidden partitioning. Let me reconsider the specific failure. The real anti-pattern: using Hive-style explicit partition columns instead of hidden partitioning. Consider two designs: (a) HIVE-STYLE (WRONG) — table has columns [ts, user_id, event, day_partition]; partitioned by day_partition (string). Users must write WHERE day_partition=\'2024-01-15\' AND ts BETWEEN .... If they omit day_partition predicate → full-table scan. Standard 2015-era pattern. Even in Iceberg tables, if you use identity partitioning on a manually-populated day_partition column, users must know that column. (b) ICEBERG-STYLE HIDDEN (RIGHT) — table has columns [ts, user_id, event]; partitioned by day(ts) transform. Users write WHERE ts BETWEEN \'2024-01-15\' AND \'2024-01-16\'. Iceberg engine automatically: (i) computes day(ts) range from ts range → identifies matching day partitions; (ii) uses manifest min/max stats for further pruning. Users never see partitioning. Specifically: (a) THE ROOT CAUSE. Many teams migrate from Hive tables to Iceberg by keeping the same table structure — including manual day_partition columns. Iceberg accepts this (identity partitioning on day_partition) but you lose hidden partitioning benefits. Users still need to know about day_partition. Change partition strategy = broken queries everywhere. (b) THE FIX — proper hidden partitioning. Recreate table with PARTITIONED BY (day(ts)) (transform, not identity). Users query WHERE ts BETWEEN ... and get automatic pruning. Change from daily to hourly? ALTER TABLE ... REPLACE PARTITION FIELD day(ts) WITH hour(ts) — metadata-only, existing queries continue working. (c) THE MIGRATION PATH. From Hive-style Iceberg table: (i) create new table with hidden partitioning; (ii) INSERT INTO new SELECT * FROM old (rewrites data with new partitioning); (iii) atomic swap; (iv) drop old. Or use Iceberg\'s REPLACE PARTITION FIELD if compatible. (d) THE MEASUREMENT. Query planner output shows which partitions scanned. Trino EXPLAIN or Iceberg\'s files metadata query. Users writing full-scan queries should be alerted (BI tool query cost tracking). Standard modern lakehouse discipline. Hidden partitioning is Iceberg\'s killer feature — actually use it. Anti-pattern §05.iii captures failing to use hidden partitioning where available.

iv
The wrong table format for the workload
"We chose Hudi for our analytical warehouse because a blog post said it was 'lakehouse'. Now we\'re fighting COW rewrite performance on batch inserts and our engine support is narrower than Trino/DuckDB/Snowflake native Iceberg."

Table format choice affects engine ecosystem, write patterns, and operational complexity. Choosing based on generic advice (rather than workload characteristics) creates specific mismatches. Consider the specific fits: (a) ICEBERG for MULTI-ENGINE + OPEN FORMAT — broadest engine support (Trino, Spark, DuckDB, Snowflake, ClickHouse, Athena, Doris, StarRocks all native); catalog choices; hidden partitioning; format-agnostic. Standard modern default. (b) DELTA for DATABRICKS + STREAMING — deep Spark integration; best streaming reads/writes; Databricks Photon engine is Delta-native. Choose if Databricks is your primary compute + you need mature streaming from day one. (c) HUDI for UPSERT-HEAVY CDC — record-level indexing enables fast upserts; MOR tables handle write-heavy loads by writing delta files (compacted async); incremental queries for CDC consumption. Choose if workload is dominated by upserts (Uber-style CDC-heavy). The specific mismatches: (a) HUDI FOR READ-HEAVY ANALYTICAL — engine support narrower than Iceberg; COW rewrites entire files on update (slow for batch inserts); Trino support less mature. Wrong choice for typical analytical warehouse. (b) ICEBERG FOR EXTREME-UPSERT CDC — Iceberg\'s row-level delete + upsert semantics improved in 2023+ (delete files, merge-on-read) but still narrower than Hudi\'s record-level indexing for high-frequency upsert workloads. May work but Hudi is genuinely better for that specific case. (c) DELTA OUTSIDE DATABRICKS — Delta works with Trino/Spark/DuckDB but you pay Databricks-optimization tax (some features Databricks-only or Spark-only); engine support narrower than Iceberg. Wrong default outside Databricks-heavy shops. The fix: (i) MATCH FORMAT TO WORKLOAD — enumerate top workloads (batch analytics, streaming ingestion, CDC upserts, ML training, ad-hoc queries), match to format capabilities. (ii) DEFAULT TO ICEBERG — for new deployments in 2025, Iceberg is the industry-standard baseline unless specific reason (Databricks-native, high-frequency upsert workload). (iii) UNDERSTAND CONVERGENCE — Delta Uniform enables Delta ↔ Iceberg interop; Databricks acquiring Tabular ($2B, 2024) signals convergence. Format lock-in less severe than 2020. (iv) MIGRATE IF WRONG — Iceberg + Delta have "adopt existing data" flows; migration is engineering-week not project. Anti-pattern §05.iv captures choosing table format without workload analysis.

v
The missing maintenance jobs
"Our Iceberg table has been in production 2 years. We never ran snapshot expiration or compaction. Metadata queries take 5 minutes; simple queries take 30. There are 3M orphaned files consuming 40TB of S3 that we\'re paying for."

Lakehouse tables require maintenance jobs to stay healthy: compaction (small files), snapshot expiration (old snapshots + orphaned data files), manifest rewrite (metadata bloat), stats refresh. Skipping maintenance produces measurable decay in query performance and S3 cost. Specifically: (a) THE MECHANISMS OF DECAY. (i) SMALL FILES — streaming or frequent writes accumulate → query metadata overhead grows → slow queries (§05.ii). (ii) SNAPSHOT ACCUMULATION — every write creates a snapshot; over 2 years with hourly writes = 17,520 snapshots. Manifest lists grow; metadata operations slow. Time travel becomes cluttered. (iii) ORPHANED FILES — replace/delete operations mark old data files as no longer referenced in current snapshot, but files remain in S3 until explicit cleanup. Over years, "orphaned but paid for" files can grow to significant fraction of table size. (iv) MANIFEST BLOAT — many small manifests instead of consolidated ones; planning overhead per query. (v) STALE STATS — column min/max stats in manifests get less accurate as data churns; predicate pushdown less effective. (b) THE MAINTENANCE OPERATIONS. (i) COMPACTION (Iceberg rewrite_data_files, Delta OPTIMIZE, Hudi async compaction) — merges small files into larger. Frequency: hourly for hot partitions, daily for warmer. (ii) SNAPSHOT EXPIRATION (Iceberg expire_snapshots, Delta VACUUM, Hudi cleaning) — deletes snapshots older than retention (e.g., 7 days) + associated data files no longer referenced. Frequency: daily. Critical for controlling S3 cost. (iii) MANIFEST REWRITE (Iceberg rewrite_manifests) — consolidates many small manifests. Frequency: weekly typical. (iv) ORPHAN FILE CLEANUP (Iceberg remove_orphan_files, Delta VACUUM) — deletes S3 files not referenced by any snapshot within retention. Frequency: weekly. Requires care (don\'t delete files needed for time travel). (v) STATS REFRESH — Iceberg refreshes stats during commits; Delta requires explicit ANALYZE TABLE. Frequency: after major writes. (c) THE OPERATIONAL DISCIPLINE. Modern lakehouse platforms handle maintenance: (i) DATABRICKS DELTA — auto-compaction, auto-optimize, Delta Live Tables automate everything. (ii) SNOWFLAKE ICEBERG — Snowflake manages maintenance for Snowflake-managed tables. (iii) TABULAR / STARBURST / DREMIO — commercial platforms provide managed maintenance. (iv) SELF-HOSTED — orchestrate via Airflow/Dagster/Prefect: daily compaction + snapshot expiration + weekly manifest rewrite + monthly orphan cleanup. Standard modern lakehouse ops. (d) THE FIX. Add maintenance job cadence to standard runbook: (i) HOURLY: compaction of hot partitions; (ii) DAILY: snapshot expiration (retention 7-30 days); (iii) WEEKLY: manifest rewrite + orphan cleanup. Alert when maintenance jobs fail or take > N hours. Standard discipline. Anti-pattern §05.v captures skipping maintenance entirely.

The composite pattern across all five is that lakehouse failure modes reflect specific engineering understanding gaps that Expert-tier competence addresses. Raw Parquet without table format misses that ACID + time travel + schema evolution are baseline for serious analytical infrastructure — free with Iceberg/Delta/Hudi. Small files problem misses that streaming writes need compaction cadence — standard maintenance job. Not using hidden partitioning misses Iceberg\'s killer feature — use partition transforms, not manual partition columns. Wrong table format misses that format ecosystem + write patterns + engine support matter — match format to workload, default Iceberg. Missing maintenance jobs misses that lakehouse tables require operational discipline — compaction + snapshot expiration + orphan cleanup + manifest rewrite on a cadence. Each has specific fixes: (a) migrate to Iceberg/Delta/Hudi; (b) compaction jobs on cadence; (c) hidden partitioning via transforms; (d) match format to workload with Iceberg as default; (e) standard maintenance runbook. Getting lakehouse architecture right is the specific engineering discipline that turns "our data lake is a graveyard" into "we query petabyte tables in seconds with ACID and time travel and any engine."

Every lakehouse regret is raw Parquet, small files, hidden partitioning not used, wrong table format, or missing maintenance. Standard modern discipline avoids all five. Expert-tier competence recognizes them instantly.
§ 06 — Eight words for the lakehouse conversation

Vocabulary,
for the table-format case.

The terms that show up in every lakehouse design review, every Iceberg vs Delta debate, every catalog choice discussion.

Table Format
/ˈteɪbəl ˈfɔːmæt/
Metadata specification that turns a directory of Parquet files into an ACID-transactional table. Apache Iceberg, Delta Lake, Apache Hudi. Adds snapshots, time travel, schema evolution, hidden partitioning to raw columnar storage. Foundational primitive of modern lakehouse.
Snapshot
/ˈsnæpʃɒt/
Immutable description of "which data files exist in this table at this point in time". Each write creates a new snapshot; catalog holds pointer to current one. Commit = atomic pointer swap. Foundation of ACID + time travel in all modern table formats.
Time Travel
/taɪm ˈtrævəl/
Query historical snapshots by ID or timestamp. SELECT ... FOR VERSION AS OF snap_id or FOR TIMESTAMP AS OF ts. Enables reproducibility (ML training), audit (compliance), recovery (ROLLBACK TO ...). Standard lakehouse feature.
Hidden Partitioning
/ˈhɪdən pɑːˈtɪʃənɪŋ/
Iceberg innovation: partition transforms (day(ts), bucket(user_id, 128)) recorded in metadata. Users query logical columns; engine applies transforms + prunes automatically. Change partition strategy without breaking queries. Killer Iceberg feature.
Schema Evolution
/ˈskiːmə ˌɛvəˈluːʃən/
Add/rename/drop columns via metadata-only operation, no file rewrites. Enabled by stable column IDs (Iceberg) or column mapping (Delta 2022+). Existing files interpreted via current schema. Enables agility on petabyte tables. Standard modern lakehouse capability.
Manifest File
/ˈmænɪfɛst faɪl/
Avro file listing subset of data files with per-file metadata (path, size, partition, min/max stats). Snapshot → manifest list → manifests → data files. Multi-level design enables efficient partial reads via metadata pruning at query planning time.
Compaction
/kəmˈpækʃən/
Maintenance operation merging many small Parquet files into fewer large ones. Iceberg rewrite_data_files, Delta OPTIMIZE, Hudi async compaction. Prevents small-files problem from streaming ingestion. Standard hourly/daily job.
Catalog
/ˈkætəlɒɡ/
Metadata coordinator tracking current snapshot per table + governance. AWS Glue (managed), Nessie (git-like), Polaris (Snowflake open), Unity (Databricks), Hive Metastore (legacy). Catalog choice affects engine compatibility + governance features. Foundation of ACID commits (atomic pointer swap).
§ 07 — Knowledge check

Five questions.
The lakehouse intuition.

Test the lakehouse understanding. Click an answer; explanation drops in instantly.

QUESTION 1 OF 5
Loading question...
Score: 0 / 5
5 / 5

Lake earned.

Perfect. Table format internals, hidden partitioning, ACID commits via atomic pointer swap, multi-engine composition — the specific engineering discipline for modern lakehouse infrastructure. Next: M.63.

§ 08 — The recap

Three ideas to
carry forward.

The composite understanding that turns "our data is stuck in Snowflake" into "we chose Iceberg on S3 for open format, Trino for interactive query, Spark for ML, DuckDB for local — with hidden partitioning, ACID, and time travel across the entire platform."

i

The table format unifies lake + warehouse

Not raw Parquet (no ACID, no time travel, no schema evolution). Not proprietary warehouse (vendor lock-in, expensive at scale). The modern lakehouse: table format metadata layer (Iceberg/Delta/Hudi) over cheap object storage. ACID transactions + time travel + schema evolution + hidden partitioning on S3 pennies-per-GB storage.

ii

Iceberg is the default; Delta for Databricks; Hudi for CDC

For new deployments in 2025, Iceberg is the industry-standard baseline — broadest engine support, hidden partitioning, format-agnostic, catalog choice. Delta continues where Databricks is central (Uniform bridges to Iceberg). Hudi remains best for upsert-heavy CDC. Understand the convergence — Databricks $2B Tabular acquisition, Delta Uniform, Snowflake Polaris, Unity going open.

iii

Multi-engine composition is the point

One storage layer. Six query engines. Trino for interactive SQL, Spark for batch + ML, DuckDB for local, Snowflake for warehouse-style, ClickHouse for analytical scale, Athena for serverless. All on the same Iceberg tables. Add/remove engines without data migration. This is the lakehouse promise fulfilled.

↓ UP NEXT · PHASE J CONTINUES

M.63 — Data mesh
and data contracts.

The next Expert module. Beyond centralized data platforms — Data Mesh treats data as a product, distributed across domain-owned teams, with data contracts (schema + SLA + semantics) as the interface. The organizational architecture that scales data platforms past centralized bottlenecks.

Continue to Module 63 →