Skip to main content
Iceberg supports in-place table evolution - you can evolve a table schema or change partition layout without costly data rewrites or table migrations. This is a fundamental advantage over traditional table formats.

Why Evolution Matters

Traditional table formats make schema and partition changes expensive:
Hive Example: Changing from daily to hourly partitions requires:
  1. Creating a new table with the new partition scheme
  2. Rewriting all historical data to the new table
  3. Updating all queries to use the new table name
  4. Managing the migration cutover period
Iceberg eliminates these costs through metadata-only evolution operations.

Schema Evolution

Iceberg supports comprehensive schema changes as metadata operations:

Supported Operations

Add

Add new columns to the table or nested structs

Drop

Remove existing columns from the table or nested structs

Rename

Rename existing columns or fields in nested structs

Update

Widen column types using safe type promotions

Reorder

Change the order of columns or struct fields

Default Values

Set initial and write defaults for fields (v3+)

Adding Columns

Add new columns anywhere in the schema:
When a column is added:
  • It gets a new, unique field ID
  • Existing data files don’t contain the column
  • Reads return null (or the default value) for old files
  • New writes include the column

Dropping Columns

Remove columns from the current schema:
When a column is dropped:
  • It’s removed from the current schema
  • The field ID is never reused
  • Old data files still contain the column (not rewritten)
  • Reads don’t return the column
  • The column can be added back with a new field ID

Renaming Columns

Change column names without affecting data:
When a column is renamed:
  • The field ID stays the same
  • Data files are unchanged
  • Both old and new queries work immediately

Type Promotion

Widen column types using safe promotions:
Valid type promotions: | From | To | Notes | |------|----|----- -| | int | long | Safe - no data loss | | float | double | Safe - no precision loss | | decimal(P,S) | decimal(P’,S) | Only widen precision (P’ > P) | | date | timestamp, timestamp_ns | v3+ only |
Promotion from timestamp to timestamptz is not allowed as it changes semantic meaning.

Reordering Columns

Change the column order in query results:
Column order changes:
  • Affect the order in SELECT * queries
  • Don’t require data file rewrites
  • Don’t affect column identification (still by field ID)

Using Spark SQL

Correctness Guarantees

Iceberg guarantees that schema evolution changes are independent and free of side-effects:
Each column has a unique field ID. Adding column_b will never accidentally read data that was written as column_a.Why this matters: Formats that track columns by name can reuse a deleted column’s name, causing data corruption.
Removing column_a doesn’t change the values in column_b or any other column.Why this matters: Formats that track columns by position must shift all subsequent columns when one is deleted.
Promoting count from int to long doesn’t change values in any other column.Why this matters: Column updates are isolated and predictable.
Moving email before name doesn’t change which data belongs to which column.Why this matters: Field IDs, not positions, identify columns.
These guarantees are possible because Iceberg uses unique field IDs to track columns, not names or positions.

Partition Evolution

Iceberg allows changing partition layout without rewriting data:

How It Works

When you evolve a partition spec:
  1. Old data keeps its partition layout - Files written with the old spec are unchanged
  2. New data uses the new layout - New writes use the updated partition spec
  3. Metadata tracks both - Each partition spec has a unique ID
  4. Split planning - Queries plan old and new layouts separately

Partition Evolution Example

A logs table starts with monthly partitions, then switches to daily:

Why Partition Evolution Works

Iceberg’s hidden partitioning makes evolution possible:
  • Queries filter on source columns (ts), not partition values
  • Iceberg derives appropriate partition filters for each spec
  • Users don’t need to know about partition layout changes
  • Old and new data coexist seamlessly

Using Spark SQL

Using Java API

Sort Order Evolution

Iceberg also supports evolving the sort order:
When sort order changes:
  • Old data keeps its original sort order
  • New data is written with the new sort order
  • Engines can choose whether to sort (or write unsorted if expensive)

Evolution Best Practices

Create a table branch or copy to test evolution operations before applying to production.
While technically allowed (with new field ID), reusing names can confuse users and queries.Better to use a new name: customer_email_v2 instead of reusing customer_email.
Monitor partition file sizes:
  • Too large (> 1GB) → Consider finer granularity (daily → hourly)
  • Too small (< 100MB) → Consider coarser granularity (hourly → daily)
When adding required fields in v3, always set a default value:
Use table properties to track significant schema evolution:

Limitations and Constraints

Type Promotion Restrictions:
  • Cannot promote if a partition field uses the source column with an incompatible transform
  • Example: Cannot promote date to timestamp if bucket(date) is a partition field (hash would change)
Struct Evolution Restrictions:
  • Cannot convert a primitive to a struct or vice versa
  • Cannot move fields in/out of nested structs
  • Cannot change struct field IDs
Map Key Evolution:
  • Cannot add or drop struct fields in map keys (would change equality semantics)

Migration Scenarios

Migrating from Hive

Evolve Hive partition columns into hidden partitions:

Changing Partition Granularity

Gracefully transition from coarse to fine granularity:

Learn More

Schemas

Understand Iceberg’s schema structure and field IDs

Partitioning

Learn about partition transforms and hidden partitioning

Branching

Use branches to test schema changes safely