Skip to content

feat(antd): cap ant-core's chunk cache (--chunk-cache-capacity, default 64) - #314

Merged
Nic-dorman merged 1 commit into
mainfrom
nic/v2-1500-antd-chunk-cache-cap
Oct 12, 2026
Merged

Nic-dorman merged 1 commit into
mainfrom
nic/v2-1500-antd-chunk-cache-cap

Conversation

@Nic-dorman

Copy link
Copy Markdown
Member

Summary

ant-core keeps every chunk it fetches in an in-memory LRU, ChunkCache, whose default capacity is 1,024 chunks. Chunks are up to ~4 MiB, so the cache can hold ~4 GiB, and antd never set a size. One multi-GB download fills it. While testing #313 on a devnet, reading a 4.5 GiB object end to end took antd's RSS from ~520 MiB to 4,654 MiB: the baseline plus a full cache.

This PR builds antd's client with ChunkCache::new(--chunk-cache-capacity), default 64 chunks (~256 MiB).

What changes

  • --chunk-cache-capacity / ANTD_CHUNK_CACHE_CAPACITY, in chunks, default 64. It is applied where antd builds its client, with ant-core's public Client::with_chunk_cache, and logged in the startup client config resolved line.
  • 0 is rejected at parse time, as are non-numbers. ChunkCache::new(0) silently falls back to 1,024, the opposite of what a caller passing 0 would expect.
  • 1024 restores the old behaviour.
  • Docs: a row in the antd README configuration table, and the flag's --help text.

Why 64

The cache's useful hits are small and close together:

64 chunks keeps those, with room for several concurrent objects, without holding a whole download in memory. A deployment with RAM to spare and repeat reads of large objects can raise it.

Compatibility

No API or wire change. A daemon now holds at most ~256 MiB of cached chunks instead of ~4 GiB by default. Reads beyond what the cache holds are fetched from the network again, which is what already happened past 1,024 chunks.

The change is independent of #313; the two touch neighbouring lines in antd/src/main.rs and merge cleanly. The devnet run below used a build of both together, because the multi-GB check reads through #313's range endpoints.

Test evidence

Unit tests: antd 98 pass, 2 of them new: the default is 64, and 0 and non-numbers are rejected. fmt, clippy -D warnings, doc and test all pass, run as CI runs them.

Multi-GB, on a 25-node devnet. The same 4.5 GiB run as #313's (1,154 data chunks, 38 ranges over REST and gRPC, every byte compared with the source file) was run with this branch merged onto #313. antd logged chunk_cache_capacity=64 at startup. Result: ALL PASS, with no ERROR or WARN lines. Against #313 alone, i.e. ant-core's 1,024-chunk default:

1,024 (before) 64 (this PR)
Peak RSS, whole object as bytes=0- 4,654 MiB 887 MiB
Peak RSS, 1 GiB open-ended range 1,727 MiB 903 MiB
Whole-object throughput 69.9 MB/s 67.4 MB/s
Small ranges: DataMap chunks from cache every request every request
  • Memory. antd sits at ~510–520 MiB after the uploads in both runs, so the cache cap is what changed. The 887 MiB peak is that baseline, plus a full 64-chunk cache (~256 MiB), plus the range windows in flight.
  • Re-fetches, the expected cost. A chunk read more than 64 chunks ago is fetched again rather than served from memory. After the 300 MiB range, the 1 GiB range fetched its 258 chunks plus the object's 3 DataMap chunks, where the 1,024 cache had 15 of them in memory. Each chunk is still fetched once within a read, and throughput is unchanged within run-to-run noise.

1024 restores the old capacity by construction: it is ant-core's own default, ChunkCache::with_default_capacity. It was not re-run separately; the "before" column is that configuration.

Not addressed here: the ~510 MiB antd holds after a 4.5 GiB upload. It is the same at either cap, and the first reads after the upload found nothing cached, so it isn't the chunk cache.

🤖 Generated with Claude Code

ant-core keeps every chunk it fetches in an in-memory LRU, ChunkCache,
whose default capacity is 1024 chunks. Chunks are up to ~4 MiB, so the
cache can hold ~4 GiB, and antd never set a size. One multi-GB download
fills it: on a devnet, reading a 4.5 GiB object end to end took antd's
RSS from ~520 MiB to 4,654 MiB, the baseline plus a full cache.

antd now builds its client with ChunkCache::new(--chunk-cache-capacity),
default 64 chunks (~256 MiB). That keeps the cache's useful hits, an
object's DataMap chunks on repeat reads and neighbouring ranged reads,
without holding a whole download in memory. ANTD_CHUNK_CACHE_CAPACITY
sets it from the environment, and 1024 restores the old behaviour.

0 is rejected at parse time: ChunkCache::new(0) silently falls back to
1024, the opposite of what a caller passing 0 would expect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@dirvine dirvine left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Six-seat independent review panel — PR #314 (antd chunk-cache cap)

Reviewed head: 315de6f08c84507e93b7a37d6da04e248dd7dd6b (branch nic/v2-1500-antd-chunk-cache-cap → main). 3 files, +48/−3. CI on this head: all green (Check antd, antd-rust, antd-js, security audit, third-party notices).

Summary

Adds --chunk-cache-capacity / ANTD_CHUNK_CACHE_CAPACITY (default 64, min 1) and passes the value to ant-core via Client::from_node(...).with_chunk_cache(ChunkCache::new(n)) in antd/src/main.rs. Previously antd inherited ant-core's default cache of 1024 chunks (~4 GiB at ~4 MiB/chunk), which a single multi-GB download would fill. The change is small, correctly wired, tested, and documented. No blocking defects found by any seat.

Per-seat verdicts

Seat Tool Verdict Key findings
1 gpt-5.1-codex (via OpenRouter) APPROVE clap plumbing, const, and flow into main() correct; tests assert default and rejection of 0/−1/garbage
2 gpt-5.1-codex (via OpenRouter) APPROVE wiring clean; ant-core claims marked unverifiable from supplied materials (verified separately below)
3 gpt-5.1-codex (via OpenRouter) APPROVE naming/env conventions consistent with existing ANTD_* flags; README arithmetic correct (~4 MiB × 64 ≈ 256 MiB, cross-checked against the existing "~4 MB per PUT" note in config.rs)
4 gpt-5.1-codex (via OpenRouter) APPROVE two new unit tests adequate for the surface; no other config tests need updating; no CI impact
5 gpt-5.1-codex (via OpenRouter) APPROVE-WITH-CONCERNS 16× default shrink (~4 GiB → ~256 MiB) may surprise deployments with large repeat/ranged read sets; recommend release/upgrade note
6 GLM-5.2 (OpenRouter, independent model seat) APPROVE-WITH-CONCERNS agrees on correctness; flags the default as a behaviour change worth release notes; suggests (judgement call) a higher floor than 1

Dissent: none. Seats 5 and 6 carry the only concerns, both non-blocking and of the same kind (default-change communication).

Blocking issues

None.

Non-blocking findings

  1. Default-change communication (seats 5, 6) — the effective cache for existing antd deployments drops from ~4 GiB to ~256 MiB. Workloads that range-read or repeat-read more than 64 distinct chunks will now re-fetch cold data unless operators raise the flag. Recommend a line in the next release notes: what changed, why (memory bound), and how to restore a larger cache.
  2. Capacity floor (seat 6, judgement call) — 1 is accepted but effectively disables the cache while keeping LRU bookkeeping. A floor of e.g. 8 could protect naive users; not worth blocking on.

Claim checks (panel-verified against the pinned ant-core checkout, ant-client @ 9112d68)

The codex seats could not see ant-core source and marked the ant-core claims unverifiable; the coordinator verified them directly:

  • ChunkCache::new(0) falls back to 1024 — VERIFIED. ant-core/src/data/client/cache.rs:13,25-37: DEFAULT_CACHE_CAPACITY = 1024; new() maps 0 → default. The test comment in this PR is accurate.
  • Default 1024 ≈ 4 GiB; entries hold full chunk data — VERIFIED. Cache value type is Bytes of full chunk content (cache.rs:17); ~4 MiB/chunk × 1024 ≈ 4 GiB. 64 × ~4 MiB ≈ 256 MiB (README row is accurate).
  • with_chunk_cache exists and is the right call site — VERIFIED. ant-core/src/data/client/mod.rs:895 defines Client::with_chunk_cache(self, ChunkCache) -> Self; antd applies it to the daemon's client, which is the only cache-holding client in the process.
  • README row, env var, default, min-1 — VERIFIED against antd/src/config.rs and antd/README.md (all seats).

Limitations

  • Seats ran as static inspection only: no builds, runs, or benchmarks were performed by the panel (CI on this exact head is green and is the execution evidence).
  • Quantitative memory figures use the ~4 MiB chunk size stated in the repo; measured footprint was not benchmarked.

Verdict

APPROVE — no blocking issues; one non-blocking recommendation (release note for the default change).

@Nic-dorman
Nic-dorman merged commit 9d8fcc6 into main Oct 12, 2026
5 checks passed
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.

2 participants