Hive
feat(kura): raise the Xcode CAS artifact cap from 25 MiB to 256 MiB
GitHub issue · Closed
What changed
MAX_XCODE_BYTES goes from 25 MiB to 256 MiB, with a comment documenting the constraint chain.
Why / root cause
Xcode’s compilation cache stores every task’s outputs as CAS objects, and app-shaped projects have a heavy artifact tail (objects with fat debug info, asset-catalog outputs, bundles) that exceeds 25 MiB. Those uploads get a 413 from Kura, which the daemon experiences as a dropped connection mid-upload. The affected tasks can never publish, so they form a permanent-miss set: every rebuild recompiles them AND re-attempts the doomed upload.
Benchmarking the Mastodon fixture on a staging runner quantified it:
- 2,559 failed
saveCASArtifactuploads per warm build (plus 217 failed keyvalue puts, some blocking until timeout) - cache hit rate plateauing at 81-89% of 815 cacheable tasks, never reaching 100%
- warm cached build 139.7 s vs 56.0 s with caching disabled (2.5x net-negative)
The inversion is not runner-specific: the June 23 production benchmark grid shows the same on third-party M4 runners against prod Kura (Mastodon xcode-cache 59.1 s vs 50.0 s no-cache), which runs the same constant. CLI-shaped projects (small artifacts, e.g. the tuist repo itself) never trip the cap, which is why this stayed hidden.
Why 256 MiB is safe
- Memory: unaffected. Uploads stream to a temp file (
read_request_to_temp), never into RAM. - Tmp disk: already governed. The tmp dir has its own budget (default 8 GiB) with 503 backpressure; concurrent large uploads are bounded by design.
- Total cache budget: unchanged.
KURA_CAS_CAPACITY_BYTES/ the disk-percent policy still caps overall usage; a larger per-object cap does not grow the cache. The only effect is ring granularity: large objects consume segment space faster, marginally shortening retention for large-artifact accounts. - Segment architecture: respected. Segments rotate at 512 MiB; 256 MiB stays well under, so rotation never sees an oversized object.
- Precedent: Gradle artifacts already use this exact path with a 100 MiB cap; Xcode gets more because its output tail is heavier.
Impact
For app-shaped projects this is the difference between the Xcode cache being net-negative and functional: with the tail publishable, hit rates can reach ~100% and the per-build failed-upload storm disappears. Follow-up (separate PR): a CLI-side size gate with a negative cache so artifacts over whatever cap remains are skipped once instead of re-attempted every build.
Validation
cargo checkclean; fullcargo testrun before merge (no test references the constant).- The end-to-end validation is the Mastodon bench re-run once this reaches staging: hit rate should climb to ~100% and the cached build should drop below the 56 s no-cache baseline or near it.
🤖 Generated with Claude Code
Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.
Start a Flight and preserve its objective, outcome, and session here.
No GitHub comments yet.