Skip to content

Spark: Add streaming-starting-offset read option to control stream start position#15472

Closed
sergiomartinswhg wants to merge 2 commits into
apache:mainfrom
sergiomartinswhg:streaming-starting-offset
Closed

Spark: Add streaming-starting-offset read option to control stream start position#15472
sergiomartinswhg wants to merge 2 commits into
apache:mainfrom
sergiomartinswhg:streaming-starting-offset

Conversation

@sergiomartinswhg
Copy link
Copy Markdown

Context

This PR addresses a common streaming pattern in Iceberg by adding the ability to dictate exactly where a Spark stream starts reading when no previous checkpoint exists.

Related PRs:

Summary

This PR adds a new streaming-starting-offset option that provides flexibility for bootstrapping Spark Structured Streaming queries. Previously, Iceberg streams defaulted to starting from the oldest snapshot or required a specific stream-from-timestamp. This PR introduces four distinct starting modes, allowing users to easily skip historical data or perform a full table scan bootstrap before switching to incremental processing.

Motivation

When starting a new stream against an existing Iceberg table, users often need specific starting points. Currently, the default behavior incrementally processes from the oldest available (unexpired) snapshot. While useful for historical backfills, this lacks support for two very common streaming architectures:

  • State Bootstrapping: Reading the entire current state of the table as a single initial batch to build downstream state, then seamlessly switching to streaming new changes incrementally.
  • Processing New Data Only: Ignoring all existing historical data to strictly process data appended after the stream is initialized.

Changes

New option: streaming-starting-offset providing four distinct starting behaviors:

Value Behavior
earliest (default) Starts from the oldest available snapshot, streaming files added by each snapshot incrementally.
latest Skips all existing data. Only snapshots appended after the stream starts are processed.
earliest-snapshot Reads all files in the oldest available snapshot as the first micro-batch, then switches to incremental.
latest-snapshot Reads all files in the current snapshot as the first micro-batch, then switches to incremental.

Compatibility & Precedence:

  • streaming-starting-offset is entirely ignored if a checkpoint already exists.
  • streaming-starting-offset and stream-from-timestamp are mutually exclusive in intent.
  • If both are set, stream-from-timestamp takes precedence to maintain backward compatibility, and a warning is logged.

Usage

// Only process new data; skip everything already in the table
val df = spark.readStream
    .format("iceberg")
    .option("streaming-starting-offset", "latest")
    .load("catalog.db.table")
// Bootstrap from a full table scan of the current snapshot, then go incremental
val df = spark.readStream
    .format("iceberg")
    .option("streaming-starting-offset", "latest-snapshot")
    .load("catalog.db.table")

All feedback and reviews are highly welcome!

@github-actions
Copy link
Copy Markdown

This pull request has been marked as stale due to 30 days of inactivity. It will be closed in 1 week if no further activity occurs. If you think that’s incorrect or this pull request requires a review, please simply write any comment. If closed, you can revive the PR at any time and @mention a reviewer or discuss it on the dev@iceberg.apache.org list. Thank you for your contributions.

@github-actions github-actions Bot added the stale label Mar 30, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 6, 2026

This pull request has been closed due to lack of activity. This is not a judgement on the merit of the PR in any way. It is just a way of keeping the PR queue manageable. If you think that is incorrect, or the pull request requires review, you can revive the PR at any time.

@github-actions github-actions Bot closed this Apr 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant