<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/ducklake-0-3-with-iceberg-interoperability-and-geometry-support-74dkmbfi0" -->

---
title: DuckLake 0.3 with Iceberg Interoperability and Geometry...
description: DuckLake 0.3 ships with the ducklake DuckDB extension (requiring DuckDB v1.4.0), adding shallow-copy interoperability with Apache Iceberg (deep and...
canonical: https://daily.dev/posts/ducklake-0-3-with-iceberg-interoperability-and-geometry-support-74dkmbfi0
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: DuckLake 0.3 with Iceberg Interoperability and Geometry Support | daily.dev
og:description: DuckLake 0.3 ships with the ducklake DuckDB extension (requiring DuckDB v1.4.0), adding shallow-copy interoperability with Apache Iceberg (deep and...
og:url: https://daily.dev/posts/ducklake-0-3-with-iceberg-interoperability-and-geometry-support-74dkmbfi0
og:image: https://api.daily.dev/og/posts/74DkMBfi0.png
og:image:alt: DuckLake 0.3 with Iceberg Interoperability and Geometry Support
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# DuckLake 0.3 with Iceberg Interoperability and Geometry Support

**[DuckLake Blog](https://daily.dev/sources/ducklake)** · 7 min read · 0 upvotes · 0 comments

## Summary

DuckLake 0.3 ships with the ducklake DuckDB extension (requiring DuckDB v1.4.0), adding shallow-copy interoperability with Apache Iceberg (deep and metadata-only copies, plus querying historical Iceberg snapshots as DuckLake tables), MERGE INTO support for upserts and conditional deletes, a new CHECKPOINT statement for maintenance tasks, a per_thread_output option that improved insert speed by ~25% in benchmarks, experimental geometry type support via the spatial extension, and author-commit metadata for audit trails. Existing DuckLake catalogs auto-migrate from v0.2 to v0.3 metadata schema when attached with the new extension.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://ducklake.select/2025/09/17/ducklake-03>

## Questions this post answers

### How do I copy data between Iceberg and DuckLake tables using DuckDB?

DuckDB's iceberg extension combined with the ducklake extension (DuckDB v1.4.0+) supports shallow-copy operations between the two formats using COPY FROM DATABASE, after attaching both an iceberg catalog and a ducklake database. Deep copies transfer the latest snapshot's data, while iceberg_to_ducklake() performs metadata-only copies that preserve full snapshot history, letting you query previous Iceberg table versions through DuckLake's AT (VERSION => n) syntax.

_daily.dev surfaces practical release notes like this for teams wiring Iceberg and DuckLake into the same pipeline._

### Does DuckLake support MERGE INTO for upserts?

Yes, as of DuckLake 0.3 the ducklake DuckDB extension supports MERGE INTO, since DuckDB 1.4 added the statement. It handles WHEN MATCHED THEN UPDATE, WHEN NOT MATCHED THEN INSERT, and conditional DELETE clauses, making it useful for OLAP-style upsert workflows in systems without primary key constraints.

_Following upsert and merge semantics across database engines gets easier when release details land on daily.dev._

### How much faster are inserts in DuckLake with the per_thread_output option enabled?

Enabling per_thread_output produced roughly a 25% improvement in a benchmark inserting one billion rows, dropping copy time from 4.5 seconds to 3.4 seconds. The option is most beneficial when each thread's output is reasonably large, such as running DuckDB on an EC2 instance with high network bandwidth to S3; with many threads and small per-thread output it can instead create too many small files and hurt read performance.

_Benchmarks like this help engineers tuning DuckLake write performance decide when daily.dev-tracked options are worth enabling._

## Similar posts on daily.dev

- [DuckLake 1.0: Data Lake Format with SQL Catalog Metadata](https://daily.dev/posts/ducklake-1-0-data-lake-format-with-sql-catalog-metadata-i1k4mw1ne) · InfoQ · 0 upvotes · 0 comments
- [Iceberg Writes in DuckDB-Iceberg](https://daily.dev/posts/iceberg-writes-in-duckdb-iceberg-9cvyktizo) · DuckDB · 4 upvotes · 0 comments
- [DuckLake Architecture Deep Dive](https://daily.dev/posts/ducklake-architecture-deep-dive-yuky5mgag) · MotherDuck · 0 upvotes · 0 comments

---

Tags: [#backend](https://daily.dev/tags/backend), [#sql](https://daily.dev/tags/sql), [#duckdb](https://daily.dev/tags/duckdb), [#apache-iceberg](https://daily.dev/tags/apache-iceberg)

[View this post on daily.dev](https://daily.dev/posts/ducklake-0-3-with-iceberg-interoperability-and-geometry-support-74dkmbfi0)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"DuckLake 0.3 with Iceberg Interoperability and Geometry Support","url":"https://daily.dev/posts/ducklake-0-3-with-iceberg-interoperability-and-geometry-support-74dkmbfi0","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/ducklake-0-3-with-iceberg-interoperability-and-geometry-support-74dkmbfi0"},"datePublished":"2026-08-16T08:54:01.248Z","dateModified":"2026-08-16T08:57:27.524Z","description":"DuckLake 0.3 ships with the ducklake DuckDB extension (requiring DuckDB v1.4.0), adding shallow-copy interoperability with Apache Iceberg (deep and...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/9172580f942b97c9e7a3892f754bb01e?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/9172580f942b97c9e7a3892f754bb01e?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"DuckLake Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"DuckLake Blog","logo":"https://media.daily.dev/image/upload/s--UI6ZqFLx--/f_auto,q_auto/v1786870426/logos/ducklake?_a=BAMAMicg0","url":"https://daily.dev/sources/ducklake"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/ducklake-0-3-with-iceberg-interoperability-and-geometry-support-74dkmbfi0","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"backend,sql,duckdb,apache-iceberg","timeRequired":"PT7M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"DuckLake Blog","item":"https://daily.dev/sources/ducklake"},{"@type":"ListItem","position":3,"name":"DuckLake 0.3 with Iceberg Interoperability and Geometry Support"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/ducklake-0-3-with-iceberg-interoperability-and-geometry-support-74dkmbfi0#faq","mainEntity":[{"@type":"Question","name":"How do I copy data between Iceberg and DuckLake tables using DuckDB?","acceptedAnswer":{"@type":"Answer","text":"DuckDB's iceberg extension combined with the ducklake extension (DuckDB v1.4.0+) supports shallow-copy operations between the two formats using COPY FROM DATABASE, after attaching both an iceberg catalog and a ducklake database. Deep copies transfer the latest snapshot's data, while iceberg_to_ducklake() performs metadata-only copies that preserve full snapshot history, letting you query previous Iceberg table versions through DuckLake's AT (VERSION => n) syntax. daily.dev surfaces practical release notes like this for teams wiring Iceberg and DuckLake into the same pipeline."}},{"@type":"Question","name":"Does DuckLake support MERGE INTO for upserts?","acceptedAnswer":{"@type":"Answer","text":"Yes, as of DuckLake 0.3 the ducklake DuckDB extension supports MERGE INTO, since DuckDB 1.4 added the statement. It handles WHEN MATCHED THEN UPDATE, WHEN NOT MATCHED THEN INSERT, and conditional DELETE clauses, making it useful for OLAP-style upsert workflows in systems without primary key constraints. Following upsert and merge semantics across database engines gets easier when release details land on daily.dev."}},{"@type":"Question","name":"How much faster are inserts in DuckLake with the per_thread_output option enabled?","acceptedAnswer":{"@type":"Answer","text":"Enabling per_thread_output produced roughly a 25% improvement in a benchmark inserting one billion rows, dropping copy time from 4.5 seconds to 3.4 seconds. The option is most beneficial when each thread's output is reasonably large, such as running DuckDB on an EC2 instance with high network bandwidth to S3; with many threads and small per-thread output it can instead create too many small files and hurt read performance. Benchmarks like this help engineers tuning DuckLake write performance decide when daily.dev-tracked options are worth enabling."}}]}
```

