Skip to main content

Bassirah Technology

Architecture Patterns

Apache Iceberg Format Version 3: What Changes and How to Plan Adoption

Deletion vectors, row lineage, variant and spatial types: what Iceberg format version 3 changes, why engine support decides timing, and how to adopt it safely.

What this article covers

Apache Iceberg table specification versions 1 to 3 (complete and adopted) and the version 4 draft, Iceberg Java 1.12.0 (29 Sep 2026), and the Trino 484 Iceberg connector, as documented on iceberg.apache.org and trino.io on 2026-10-22. Commercial platforms' v3 status is out of scope.

Apache Iceberg’s table specification now has three versions that the community describes as complete and adopted. Version 3 adds new data types, column default values, row lineage, binary deletion vectors and table encryption keys. Several engines and platforms have started to support it during 2026, and the question many teams now face is whether, and when, to move existing tables to it.

The decision is not a software upgrade. It is a change to the table itself, and every engine that reads or writes the table must understand the new version. This article explains what version 3 changes, what it means for mixed-engine lakehouses, and a sequence for adopting it without stranding readers.

What format version 3 adds

The Iceberg table specification states that versions 1, 2 and 3 are complete and adopted by the community, and that version 4 is under active development and has not been formally adopted. It lists the version 3 additions as:

  • new data types: nanosecond timestamp and timestamptz, unknown, variant, geometry and geography
  • default value support for columns
  • multi-argument transforms for partitioning and sorting
  • row lineage tracking
  • binary deletion vectors
  • table encryption keys

The specification also explains why the version number matters. It is incremented when new features would break forward compatibility, meaning older readers would not read the new features correctly. Tables may continue to be written with an older version so that engines that have not implemented the new features can still use them.

That last point is the core of the decision. Version 2 remains a valid, supported choice. Version 3 is worth adopting when its features solve a problem you have, and when every engine in your estate can handle it.

Deletion vectors: the change most teams notice first

Version 2 introduced row-level deletes through delete files. Version 3 changes how position deletes are stored. According to the specification’s version 3 section:

  • Deletion vectors are stored using the Puffin deletion-vector-v1 blob type.
  • Writers must merge deletion vectors, and older position delete files, so that there is at most one deletion vector per data file.
  • Writers are not allowed to add new position delete files to version 3 tables.
  • Existing position delete files remain valid in tables upgraded from version 2, and must be merged into a data file’s deletion vector when one is created.

The practical effect is that the number of delete artefacts per data file is bounded, which simplifies reading tables that receive frequent updates and deletes. The cost moves to the writer, which must merge on each commit. Teams running high-frequency MERGE or change-data-capture pipelines should test commit behaviour and retry rates on version 3 before moving production tables.

Equality deletes are not replaced in version 3. The specification’s version 4 draft lists “Writing new equality deletes is no longer allowed” as a planned change, which signals the direction of travel for streaming writers that rely on them.

Row lineage, defaults and new types

Row lineage gives each row an identifier and a last-updated sequence number. The specification defines the fields _row_id and _last_updated_sequence_number, and requires writers to maintain a table-level next-row-id. When a table is upgraded to version 3, next_row_id starts at 0. Writers that copy an existing row into a new data file must preserve its lineage values. This supports incremental processing and change tracking, but only if every writer follows the rules. One writer that drops lineage values breaks the chain for the rows it rewrites.

Column defaults are added to struct fields. The specification distinguishes write-default, used at write time, from initial-default, used to fill existing rows. It also notes that older readers will fail to read required fields populated by initial-default. That is a concrete compatibility risk for teams that add required columns with defaults.

New types include variant for semi-structured data, geometry and geography for spatial data, and nanosecond timestamps. These remove the need to store JSON as strings or spatial values as binary blobs. They also introduce a hard dependency: a table that contains a variant column cannot be read by an engine that does not support version 3.

Encryption keys are tracked in table metadata, with each snapshot naming the key it uses. Engine support for writing encrypted tables varies, as the next section shows.

Engine support is uneven: check each reader and writer

An Iceberg table is shared by design. Spark jobs, Trino queries, streaming writers, catalogs and maintenance tools may all touch it. The table can only move to version 3 when all of them can read it, and all writers can write it correctly.

The Java reference implementation has shipped version 3 work across several releases. The Iceberg releases page lists 1.10.0 (September 2025), 1.11.0 (May 2026) and 1.12.0 (29 September 2026). The 1.10.0 notes include row lineage support in readers and variant read support. The 1.12.0 notes include fixes for row lineage, default values and variant metrics, and also begin version 4 manifest work. Teams on older library versions should expect to upgrade the library before the table.

On the query engine side, the Trino Iceberg connector documentation states that support for format version 3 is experimental. It lists these limits on the research date:

  • The format_version table property accepts 1, 2 or 3, and defaults to 2.
  • Row-level updates and deletes on version 3 tables use deletion vectors.
  • The add_files and add_files_from_table procedures are not supported on version 3 tables.
  • Writing to encrypted tables is not supported.
  • Version 3 is required for tables with VARIANT columns.

The Trino 480 release notes added creating, writing and deleting from version 3 tables, with row lineage and the main maintenance procedures. Later releases added geometry and geography and experimental variant support. This is active work, and the boundaries move with each release.

Commercial platforms document their own version 3 status, which can differ by edition, region and preview stage. Record each platform’s status from its own documentation, on the date you check, rather than relying on summaries.

Upgrading a table: one direction only

Engines expose the format version as a table property. In Trino, for example, ALTER TABLE ... SET PROPERTIES format_version = ... changes it, and the connector documentation shows this for moving from version 1 to version 2. The same property is used for version 3.

The specification defines how readers interpret upgraded metadata, but it does not describe a path back to an older version. Treat the upgrade as one-way. Once a version 3 writer has added deletion vectors, row lineage or a variant column, a version 2 reader cannot use the table correctly. Restoring from a copy is the realistic rollback, so take one first.

Question Stay on version 2 when Consider version 3 when
Who reads the table? Any reader lacks version 3 support Every reader is confirmed on a supporting release
How is it written? Writers depend on new position delete files or add_files Writers handle deletion vectors and preserve lineage
What data does it hold? Flat, typed columns only Semi-structured or spatial data that needs native types
What changes downstream? No need for row-level change tracking Incremental pipelines would use row lineage
How critical is it? Shared, high-traffic, hard to restore New table, or one that can be rebuilt

A phased adoption plan

  1. Inventory engines. List every reader, writer, catalog and maintenance job per table, with the exact library or engine release.
  2. Confirm support from official documentation for each one, including limits such as unsupported procedures or encryption.
  3. Start with new tables. Create version 3 tables for new workloads that need variant, spatial types or row lineage. Leave existing tables on version 2.
  4. Test writers under load. Run representative MERGE, UPDATE and DELETE workloads, and check commit conflicts and maintenance jobs.
  5. Snapshot before upgrading. For an existing table, take a restorable copy and record the current metadata location.
  6. Upgrade a low-risk table first. Run read, write, compaction, snapshot-expiry and orphan-file cleanup on it from every engine.
  7. Expand gradually, table by table, and record the format version of each table in your catalog or data governance tooling.

Version 4 is still a draft. It is not a reason to wait, but it is a reason to keep library versions current and to avoid building tools that depend on internal metadata layouts.

How Bassirah can help

Bassirah designs and operates open lakehouses built on Apache Iceberg, described in our open Iceberg lakehouse architecture. We can inventory the engines that touch your tables, test format version 3 on non-production copies and plan a table-by-table adoption. Our support for open-source components such as Trino is independent engineering, and upstream fixes follow each community’s timeline. See also our enterprise lakehouse solution.

Independent engineering services

These are independent Bassirah engineering and support offerings. They do not imply upstream vendor or foundation endorsement, official vendor support rights, enterprise feature entitlement or maintenance guarantees.

Sources

  1. Iceberg Table Spec - Apache Iceberg
  2. Releases - Apache Iceberg
  3. Iceberg connector - Trino
  4. Release 480 (24 Mar 2026) - Trino
  5. Release 481 (11 May 2026) - Trino
  6. Release 482 (25 Jun 2026) - Trino

bassirah

Related pages

More insights

Discuss This With an Architect

Map these trade-offs against your workloads, constraints and operating model.

Talk to an Expert