Skip to content

Roll added manifests at target size and write them in parallel #3499

Open

Description

@CTTY

Is your feature request related to a problem or challenge?

SimpleSnapshotProducer (#3474) writes all data files added by a FastAppendAction into a single manifest, regardless of how many files there are. iceberg-java's FastAppend instead wraps the writer in RollingManifestWriter, which starts a new manifest once the current one reaches commit.manifest.target-size-bytes (default 8 MB; size is checked every 250 entries). A large append therefore produces several right-sized manifests, which keeps scan planning able to skip and parallelize at manifest granularity.

Java also writes the resulting manifests concurrently (SnapshotProducer.writeDataManifests on the worker pool). With a single manifest per append there is nothing to parallelize, so this only becomes useful together with rolling.

Neither is a correctness issue, so both were left out of the milestone-2 producer to keep that PR focused.

Describe the solution you'd like

  1. Rolling writer. Add a RollingManifestWriter (or equivalent) over ManifestWriter that tracks written bytes and rolls to a new path when commit.manifest.target-size-bytes is exceeded. Paths come from the producer's manifest_counter, so rolled manifests never collide across retry attempts. Check size every N entries, as Java does, rather than per entry. The writer should live in snapshot_helpers (or spec::manifest) so MergingSnapshotProducer (milestone 3) can reuse it for added and delete manifests.

  2. Parallel writes. Allocate all manifest paths up front (serially, under &mut self, recording each in owned_artifacts so a failed partial write is already on the cleanup list), then spawn one task per manifest via table.runtime().io().spawn(...) and collect with try_join_all so results stay in input order. Table is Clone, so each task can own its handle.

  3. Bound concurrency. Cap in-flight writers so a very large append does not open thousands of output streams at once.

AddedManifests.manifests is already a Vec<ManifestFile> with a group-level reuse guard, so rolling needs no change to the producer's state shape.

Related: epic #3266, milestone-2 PR #3474, spec grouping is tracked in #3500.

Willingness to contribute

I can contribute to this feature independently

Activity

  1. changed the title [-]Roll added manifests at target size and write them in parallel in SimpleSnapshotProducer[/-] [+]Roll added manifests at target size and write them in parallel[/+] on Oct 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions