Skip to content

Fix excessive memory usage in local storage range downloads - #2213

Merged
micafer merged 3 commits into
trunkfrom
fix/local-range-streaming
Nov 9, 2026
Merged

micafer merged 3 commits into
trunkfrom
fix/local-range-streaming

Conversation

@micafer

@micafer micafer commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Fix excessive memory usage in local storage range downloads

Description

Fixes #2191.

Moved from #2192.

The local driver's range-stream method reads the entire source file to determine its size, then yields the whole requested range as one chunk. Even a tiny range therefore allocates memory proportional to the source size, and chunk_size is ignored. The file-download method then buffers the complete range before writing.

Use os.fstat on the open descriptor for the size, seek directly to the requested offset, and read at most the requested chunk size and remaining range length. Write each chunk to the destination as it arrives. Preserve non-inclusive end offsets and existing range validation. Use the standard default chunk size when omitted or zero, reject negative chunk sizes, and stop on early EOF.

Add five regression test methods covering bounded/default chunks, exact range reads, incremental writes, negative chunk sizes, and early EOF. All five fail against the original implementation. Add a storage changelog entry.

A local tracemalloc experiment requested 1 KiB from a 64 MiB sparse file with chunk_size=128:

Implementation Peak traced Python allocation Output
Original 67,113,884 bytes One 1,024-byte chunk
Fixed 6,242 bytes Eight 128-byte chunks

These are allocations for this single experiment, not total process memory or a general benchmark.

Status

Done, ready for review. Local checks pass; upstream CI has not yet run.

Validation on Python 3.12.14 / Linux:

  • pytest -q libcloud/test/storage libcloud/test/test_utils.py --ignore=libcloud/test/storage/test_list_objects_filtering_performance.py: 982 passed, 12 skipped, with six additional passing subtests. Existing deprecation warnings remain.
  • All applicable prek hooks for the three changed files pass, including Black, isort, flake8, pyupgrade, and codespell.
  • git diff --check passes.

Checklist

AI assistance

Generated-by: OpenAI Codex (GPT-6)

Codex assisted with investigation, implementation, regression tests, local validation, and this description. This assistance is disclosed following the ASF Generative Tooling Guidance.

mneha05 and others added 3 commits October 5, 2026 18:28
Small range downloads currently allocate memory proportional to the source
file size and ignore the requested chunk size. File downloads also retain
the complete range before writing, which makes large local objects costly
to access under memory limits.

Fixes #2191

Generated-by: OpenAI Codex (GPT-6)
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.62%. Comparing base (18b9248) to head (9cf14e9).

Additional details and impacted files
@@            Coverage Diff             @@
##            trunk    #2213      +/-   ##
==========================================
+ Coverage   83.61%   83.62%   +0.02%     
==========================================
  Files         352      352              
  Lines       82161    82233      +72     
  Branches     8816     8840      +24     
==========================================
+ Hits        68694    68767      +73     
+ Misses      10594    10593       -1     
  Partials     2873     2873              
Files with missing lines Coverage Δ
libcloud/storage/drivers/local.py 78.63% <100.00%> (+0.67%) ⬆️
libcloud/test/storage/test_local.py 93.42% <100.00%> (+1.03%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@micafer
micafer merged commit 0317e58 into trunk Nov 9, 2026
17 checks passed
@micafer
micafer deleted the fix/local-range-streaming branch November 9, 2026 08:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Local storage range downloads buffer the source and ignore chunk_size

3 participants