
Modern Lakehouse Engineering with Iceberg and DuckDB
Master the modern, serverless data lakehouse stack. Learn to build high-performance, cost-effective analytics pipelines using Apache Iceberg for transactional storage and DuckDB for fast local and serverless querying.
The data engineering landscape has undergone a massive paradigm shift. For years, building a reliable data platform required deploying heavy, expensive, and complex JVM-based clusters running Hadoop, Spark, or proprietary cloud data warehouses. Today, a new architectural pattern has emerged: the modular, serverless data lakehouse. By decoupling storage, metadata, and compute, organizations can build highly performant, ACID-compliant data platforms at a fraction of the cost.
This learning path is designed to take you from a traditional SQL or database developer to a modern lakehouse engineer. You will master two of the most disruptive technologies in this space: Apache Iceberg, an open-source, high-performance table format for massive analytic datasets, and DuckDB, an embedded, vectorized SQL query engine designed for analytical processing. Together, these technologies allow you to build local-first development environments that scale seamlessly to production-grade cloud lakehouses.
Throughout this roadmap, you will transition from running simple local queries to designing fully automated, serverless data pipelines that handle millions of rows with sub-second query times. You will learn not just how to use these tools, but how they work under the hood, enabling you to make informed architectural decisions in your professional career.
Prerequisites
Before embarking on this learning path, you should possess a solid foundation in core data concepts and programming. This is an intermediate-level roadmap, meaning we assume you are not starting from scratch.
- Intermediate SQL: You should be comfortable with complex queries, including Common Table Expressions (CTEs), window functions, lateral joins, and query execution plans. You should understand the difference between row-oriented (OLTP) and column-oriented (OLAP) databases.
- Python Programming: Proficiency in Python is essential. You should understand virtual environments, package management, and basic data manipulation libraries like Pandas or Polars. Familiarity with PyArrow is highly beneficial but not strictly required.
- Basic Docker: You must know how to run containers, configure environment variables, mount local volumes, and orchestrate multi-container setups using Docker Compose.
- Cloud Storage Basics: A conceptual understanding of object storage (such as AWS S3, Google Cloud Storage, or Azure Blob Storage), including bucket structures, IAM policies, and API-based access, is necessary.
Phase 1: Local Analytics and Embedded SQL with DuckDB (Weeks 1-4)
The first phase focuses on mastering DuckDB as your primary analytical engine. DuckDB is often referred to as the "SQLite for Analytics." It runs embedded within your process, requires zero configuration, and features a state-of-the-art vectorized query execution engine that processes data in chunks rather than row-by-row.
Learning Objectives
- Understand the architecture of DuckDB, including its vectorized execution engine, columnar storage, and out-of-core processing capabilities.
- Query raw files (CSV, JSON, Parquet) directly from local storage and remote HTTP/S3 endpoints without loading them into a database first.
- Master DuckDB's integration with the Python ecosystem, specifically passing data zero-copy to and from Pandas, Polars, and Apache Arrow.
- Configure DuckDB's memory limits, temporary directories, and threading options to optimize performance on resource-constrained environments.
Hands-on Project 1: Local Log and Clickstream Analyzer
Build a local command-line tool that ingests and analyzes gigabytes of raw, unstructured web server logs and clickstream data.
- Step 1: Write a script to generate or download a large multi-gigabyte dataset of raw JSON and CSV logs.
- Step 2: Use DuckDB's native JSON and CSV readers to parse, clean, and structure the data using SQL.
- Step 3: Implement projection and filter pushdown by writing the cleaned data into highly optimized, partitioned Parquet files.
- Step 4: Build a lightweight analytical dashboard using Streamlit or Evidence that queries these Parquet files directly using DuckDB, demonstrating sub-second response times on millions of records.
Phase 2: Introduction to Table Formats and Apache Iceberg (Weeks 5-8)
While Parquet files are excellent for read performance, managing raw files in a data lake introduces significant challenges: there are no ACID transactions, schema evolution is difficult, and querying requires expensive file-listing operations. This is where Apache Iceberg comes in. Iceberg is a high-performance open table format that brings database-like reliability to object storage.
Learning Objectives
- Understand the limitations of traditional Hive-style partitioning and how Apache Iceberg solves them.
- Deconstruct the Iceberg specification: learn the roles of the Catalog, Metadata Files, Manifest Lists, Manifest Files, and actual Data Files.
- Master Iceberg's core features: ACID transactions (using optimistic concurrency control), hidden partitioning, partition evolution, schema evolution, and time travel.
- Set up and manage an Iceberg Catalog (such as a REST catalog, Nessie, or AWS Glue) to track table state.
- Use PyIceberg, the official Python library, to programmatically interact with Iceberg tables, write data, and inspect metadata.
Hands-on Project 2: Local Iceberg Catalog with PyIceberg and Docker
Create a complete, self-contained local lakehouse development environment using Docker Compose.
- Step 1: Spin up a Docker Compose environment containing MinIO (an S3-compatible local object store), an Iceberg REST Catalog, and a Jupyter Notebook environment.
- Step 2: Write a Python script using PyIceberg to create a new table, define its schema, and configure hidden partitioning (e.g., partitioning a timestamp column by day without creating a physical column for the day).
- Step 3: Simulate a production data stream by appending batches of data to the table. Perform a schema evolution operation (adding and renaming columns) and demonstrate that historical data remains readable without rewriting files.
- Step 4: Write a script that utilizes Iceberg's time-travel feature to query the table as of a specific snapshot ID or timestamp, and perform a rollback operation to undo an accidental data write.
Phase 3: Integrating DuckDB and Apache Iceberg (Weeks 9-12)
Now that you understand both DuckDB and Apache Iceberg, you will learn how to combine them. This integration represents the pinnacle of modern, lightweight data engineering: using DuckDB as a fast, serverless query engine on top of Iceberg's reliable, transactional storage layer.
Learning Objectives
- Understand the integration paths between DuckDB and Iceberg, including using DuckDB's native Iceberg extension and leveraging PyIceberg to pass PyArrow datasets to DuckDB.
- Analyze how DuckDB leverages Iceberg's metadata to perform partition pruning and file-level min/max statistics skipping before reading data from storage.
- Compare the performance of querying raw Parquet files versus querying Iceberg tables using DuckDB.
- Learn how to handle concurrent reads and writes, understanding how Iceberg's transactional guarantees prevent dirty reads or partial writes in a multi-engine environment.
Hands-on Project 3: Serverless Lakehouse Analytics Pipeline
Design and implement an end-to-end analytics pipeline that processes and queries data without running a persistent database server.
- Step 1: Set up a pipeline that ingests raw transactional data, processes it using PyIceberg and PyArrow, and writes it into an Iceberg table stored in your local MinIO bucket.
- Step 2: Write a Python application that uses DuckDB to execute complex analytical queries against this Iceberg table. Ensure that DuckDB is reading the metadata from the Iceberg REST Catalog to resolve the active files.
- Step 3: Profile your queries. Use DuckDB's EXPLAIN statement to verify that partition pruning is actively working (e.g., querying for a specific date range only reads the Parquet files associated with those partitions).
- Step 4: Implement a concurrent write scenario where a background process appends new data to the Iceberg table while DuckDB is executing long-running analytical queries, proving that readers never block writers and always see a consistent snapshot of the data.
Phase 4: Productionalizing and Scaling (Weeks 13-16)
In the final phase, you will transition your local lakehouse architecture to the cloud. You will learn how to manage production-scale storage, secure your catalog, and perform essential table maintenance operations to keep your lakehouse running at peak performance.
Learning Objectives
- Deploy your Iceberg catalog and storage to a cloud provider (e.g., AWS S3 with AWS Glue Catalog, or Google Cloud Storage with a REST catalog).
- Master Iceberg table maintenance: file compaction (merging small files), orphan file deletion, and snapshot expiration.
- Implement security best practices, including IAM roles, bucket policies, and fine-grained access control at the catalog level.
- Understand how to scale your architecture by integrating other engines (like Apache Spark or Trino) to write to the same Iceberg tables that DuckDB queries.
Hands-on Project 4: End-to-End Cloud Lakehouse Engine
Build and deploy a production-ready, serverless cloud lakehouse.
- Step 1: Use Infrastructure as Code (like Terraform) or cloud consoles to set up an S3 bucket and an AWS Glue Catalog (or Google Cloud equivalent).
- Step 2: Ingest a large public dataset (such as the NYC Taxi dataset or GitHub Archive) into your cloud Iceberg table.
- Step 3: Deploy a serverless execution environment (such as AWS Lambda, Google Cloud Run, or a lightweight ECS task) running DuckDB. Configure it to query the cloud Iceberg table directly, utilizing IAM roles for secure, passwordless authentication.
- Step 4: Write an automated maintenance script (run via a cron job or scheduled cloud function) that performs compaction on your Iceberg table to merge small files, deletes orphan files, and expires snapshots older than 7 days to control storage costs.
Milestones
To ensure you are on track, use these milestones as self-assessment checkpoints throughout your learning journey:
- Milestone 1 (End of Week 4): You can write a single DuckDB SQL query that joins a local CSV file with a remote Parquet file on S3, executing in under two seconds and utilizing less than 500MB of RAM.
- Milestone 2 (End of Week 8): You can explain the exact sequence of metadata file reads that occurs when an Iceberg client queries a table, and you have successfully performed a time-travel query on a local Iceberg table using PyIceberg.
- Milestone 3 (End of Week 12): You have built a pipeline where DuckDB queries an Iceberg table, and you can prove via query plans that DuckDB is skipping files based on Iceberg's partition and column-level statistics.
- Milestone 4 (End of Week 16): You have a fully automated cloud-based lakehouse where data is safely ingested, transactionally updated, queried serverlessly via DuckDB, and automatically compacted via scheduled maintenance tasks.
Common Mistakes to Avoid
As you progress through this roadmap, be mindful of these common pitfalls that plague many lakehouse implementations:
- The Small File Problem: Frequent, small writes to an Iceberg table create thousands of tiny Parquet files and massive metadata trees. This drastically slows down query performance in DuckDB. You must implement a regular compaction strategy to merge these small files into larger, optimal blocks (typically 128MB to 512MB).
- Over-Partitioning: Partitioning your Iceberg tables by high-cardinality columns (like a raw timestamp or user ID) creates an excessive number of partitions. This bloats the metadata and forces DuckDB to read thousands of manifest files, destroying query performance. Partition conservatively (e.g., by year, month, or day).
- Ignoring Catalog Synchronization: Never attempt to modify the underlying Parquet files in an Iceberg table directly through file system operations. All writes, deletes, and updates must go through an Iceberg-compliant client that updates the Catalog. Direct file manipulation will corrupt the table state and lead to data loss.
- Neglecting DuckDB Memory Limits: By default, DuckDB will attempt to use as much system memory as possible to speed up queries. In shared or resource-constrained environments (like serverless functions), this can lead to Out-Of-Memory (OOM) crashes. Always explicitly set the max_memory configuration in DuckDB to match your environment's limits.
- Forgetting to Expire Snapshots: Iceberg's time-travel feature works by keeping historical data files and metadata snapshots. If you never expire old snapshots, your storage costs will grow indefinitely, even if you delete data from the active table state. Implement a strict snapshot expiration policy.
Portfolio Outcomes
By the end of this learning path, you will have a robust portfolio demonstrating your expertise in modern data engineering:
- A Local Lakehouse Development Template: A clean, documented GitHub repository containing your Docker Compose setup (MinIO, REST Catalog, Jupyter) that other developers can use to spin up a local lakehouse in seconds.
- A Performance Benchmarking Suite: A project comparing the performance of raw file querying versus Iceberg table querying in DuckDB, complete with query plans, execution time graphs, and resource utilization metrics.
- A Production-Grade Cloud Pipeline: The code and infrastructure-as-code configurations for your serverless cloud lakehouse, demonstrating your ability to deploy secure, cost-effective, and automated data platforms in the cloud.
- A Table Maintenance Automation Script: A highly practical Python script demonstrating how to programmatically manage Iceberg table health through compaction, snapshot expiration, and orphan file cleanup.
What to Learn Next
Once you have mastered this roadmap, you are well-positioned to expand your skills into adjacent areas of the modern data stack:
- dbt (Data Build Tool): Learn how to use dbt with the dbt-duckdb adapter to build modular, tested, and documented SQL transformation pipelines directly on top of your Iceberg tables.
- Distributed Query Engines (Trino / Athena): While DuckDB is perfect for single-node and serverless querying, learn how to use Trino or AWS Athena to run distributed SQL queries over the exact same Iceberg tables when your data scales to petabytes or requires multi-user concurrency.
- Streaming Ingestion (Apache Flink / Spark Streaming): Explore how to write real-time data streams directly into Iceberg tables, enabling near-real-time analytics with DuckDB on the read path.
- Data Quality and Observability: Integrate tools like Great Expectations or Soda to validate data quality at the ingestion boundary before writing to your production Iceberg tables.
Stacks relacionados

Apache Iceberg
An open-source, high-performance table format for massive analytic datasets, bringing ACID transactions and SQL-like table behavior to object storage.

DuckDB
An embedded, high-performance analytical SQL database engine designed for in-process OLAP workloads and seamless data ecosystem integration.