fix(capsule): prune by age only, drop size-based eviction#10408
Merged
Conversation
The size-target LRU eviction counted the whole cache total but could only evict scope-aspect children. When un-evictable content (workspace/scope caps, legacy unmarked dirs) alone exceeded the target, it wiped 100% of aspect capsules across all repos and still missed the target. Computing sizes also required an expensive recursive lstat walk on every auto-prune. Auto-prune is now age + orphan based only (no size walk), so the cache self-bounds to workspaces used within --older-than and deletes are O(1).
Contributor
There was a problem hiding this comment.
Pull request overview
This PR changes capsule cache pruning to remove size-based eviction entirely, addressing cases where --size-target caused widespread eviction of scope-aspect capsules across repos sharing the same global cache and incurred expensive full-cache size walks. Pruning now relies on age- and orphan-based rules only, keeping size computation as an explicit opt-in for reporting.
Changes:
- Removed
--size-targetsupport frombit capsule pruneand its config constant (CFG_CAPSULES_MAX_SIZE_GB). - Updated auto-prune to spawn
bit capsule prune --older-than <N>only (no size target), avoiding full-cache size traversal by default. - Removed size-target enforcement logic (
applySizeTarget) from the capsule cache prune pipeline;--with-sizesremains for report byte totals.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| scopes/workspace/workspace/capsule.cmd.ts | Drops the --size-target CLI flag/config usage and only forwards age/orphan-related options to pruning. |
| scopes/harmony/cli-reference/cli-reference.mdx | Removes --size-target from the published CLI reference for capsule prune. |
| scopes/component/isolator/capsule-cache.ts | Removes size-target-based eviction and updates auto-prune spawning to prune by age only; keeps size computation opt-in. |
| components/legacy/constants/constants.ts | Removes the CFG_CAPSULES_MAX_SIZE_GB config key constant. |
GiladShoham
approved these changes
Jun 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The capsule auto-prune (
bit capsule prune --size-target 10) was wiping scope-aspects capsules across all repos sharing the global cache. With ~10 bit checkouts, every aspect capsule got evicted daily, making rebuilds slow.Root cause is in
applySizeTarget: it measured the whole cache total but could only evict scope-aspect children. When the un-evictable remainder (workspace/scope caps, ~11 GB of legacy unmarked dirs, each aspect-root's ownnode_modules) already exceeded the target, the loop evicted 100% of aspect capsules across every repo and still never reached the target. Evidence from logs: 569 removals taggedsize-target-10gbvs only 14 forolder-than-30d, and the cache stayed at 18 GB after "pruning" to a 10 GB target.Size accounting also forced an expensive recursive
lstatwalk of the entire cache on every auto-prune.Change
Drop size-based eviction entirely; prune by age + orphan only.
bit capsule prune --older-than <N>(no--size-target); no size walk → O(1) rename-to-trash deletes.applySizeTarget, the--size-targetflag, andCFG_CAPSULES_MAX_SIZE_GB.--with-sizesstays as an opt-in for byte totals in the report.The cache now self-bounds to "workspaces touched within
--older-than(default 30d)"; throwaway/temp scopes are still caught by the orphan check.