Skip to content

memory cost of deleting "outside" chunks on resize is unbounded #3650

Open

Description

@dcherian

Zarr version

3.1.5

Description

if delete_outside_chunks:
# Remove all chunks outside of the new shape
old_chunk_coords = set(self.metadata.chunk_grid.all_chunk_coords(self.metadata.shape))
new_chunk_coords = set(self.metadata.chunk_grid.all_chunk_coords(new_shape))

def all_chunk_coords(self, array_shape: tuple[int, ...]) -> Iterator[tuple[int, ...]]:
return itertools.product(
*(range(ceildiv(s, c)) for s, c in zip(array_shape, self.chunk_shape, strict=False))
)

For very large arrays (even if unpopulated), the set in resize (which has delete_outside_chunks=True by default) will take down a machine :/ .

  1. I propose delete_outside_chunks=False by default. This is a "maintenance op" and has unbounded cost with high latency stores. It should not be called in a "normal" workflow.
  2. delete_outside_chunks can be a LOT smarter. We know new shape and old shape; so we can construct "outside" chunk coords directly from the diff of the shapes. In particular, simply extending the size of a dimension requires no deletion (!!!).

Steps to reproduce

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "zarr@git+https://github.com/zarr-developers/zarr-python.git@main",
# ]
# ///
#
# This script automatically imports the development branch of zarr to check for issues

import zarr
import numpy as np

store = zarr.storage.MemoryStore()

# Create the array with specified shape and chunks
arr = zarr.create(
    shape=(143, 7, 668160, 1336320),
    chunks=(1, 1, 928, 928),
    dtype=np.float32,
    store=store,
    overwrite=True
)
arr.resize((144, *arr.shape[1:]))

Additional output

No response

Activity

  1. added
    bugPotential issues with the zarr-python library
    on Jan 12, 2026
  2. changed the title [-]memory cost of deleting old chunks on resize is unbounded[/-] [+]memory cost of deleting "outside" chunks on resize is unbounded[/+] on Jan 13, 2026
  3. d-v-b commented on Jan 13, 2026

    @d-v-b
    Contributor

    +1 to deferring cleanup activities to a separate routine. I wonder if a function like prune_chunks(array_metadata, store, path) would fit the bill here. This would remove all chunks that are a) consistent with the chunk grid and b) outside the shape of the array.

  4. jakenotjay commented on Feb 11, 2026

    @jakenotjay
    Contributor

    Exactly what Deepak described took down one of our processes yesterday when updating our icechunk stores to have a single new timestep (it's a very large array), there are no chunks to remove, so this code block should ideally not even be touched.

    Instead we saw huge memory usage >20GB and an infinite hang for 2 hours.

    I've opened a PR, which temporarily mitigates this by checking if the array has only "expanded" and skips the check.

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

    bugPotential issues with the zarr-python library

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions