Skip to content

feat(orchestrator): layer-dedup-audit mark-only tool for cross-scope layer dedup - #3750

Open
AdaAibaby wants to merge 1 commit into
e2b-dev:mainfrom
AdaAibaby:feat/layer-dedup-audit
Open

AdaAibaby wants to merge 1 commit into
e2b-dev:mainfrom
AdaAibaby:feat/layer-dedup-audit

Conversation

@AdaAibaby

Copy link
Copy Markdown
Contributor

What

A read-only (mark-only) tool, cmd/layer-dedup-audit, that finds historical cross-scope duplicate template layers in the build-cache bucket and reports wasted bytes + a delete-candidate manifest. It deletes nothing.

Why

Layer caching is content-addressed (cache.HashKeys = sha256 over base + keys, no team), but the storage path is prefixed by cacheScope, and the API historically set cacheScope = teamID (create_template.go, upload_template_layer_files.go). So two teams that build byte-identical layers each hold a private copy at {teamID}/files/{hash}.tar (+ the tiny {teamID}/index/{hash}). The content hash already proves the bytes are identical, so these copies are reclaimable in a single-trust-domain deployment.

This tool quantifies that waste and emits candidates; it pairs with the opt-in shared cache scope (#3748 / #3749) which prevents new duplicates.

How

Lists the bucket, keeps {scope}/files/{hash}.tar, groups by hash, flags any hash present under >1 scope. Keeps the oldest copy per hash as canonical, lists the rest (with their paired index/{hash}) in out/candidates.json. Prints scanned/total/wasted summary + top wasters. Self-contained S3 client (TOS/MinIO via S3_USE_PATH_STYLE).

Relation to #3742 (template-gc)

Orthogonal and complementary — both mark-only, each on a different bucket:

template-gc (#3742) this tool
bucket TEMPLATE_BUCKET {buildID}/ BUILD_CACHE_BUCKET {scope}/files/{hash}.tar
criterion liveness (orphans outside live-root ancestor closure) content (same hash, multiple scopes)
reclaims unreferenced build artifacts (memfile/rootfs) cross-scope duplicate layer tars

template-gc cannot dedup cross-team duplicates: teamA/teamB each have a live template pointing at their own buildID, so both buildIDs are live roots and both are kept. This tool cannot reclaim orphan build artifacts in the template bucket. They compose: shared scope (#3749) stops new duplicates, existing templates converge on rebuild, template-gc then reaps the orphaned old builds, and this tool marks the build-cache layer tars that will never be hit again.

Safety

Deletes nothing. Deletion is a separate operator-gated step over candidates.json (quarantine then delete) — same posture as #3742: a cache is more dangerous than reading ground truth, a wrong delete is permanent corruption.

Follow-up

Once #3742 merges, refactor onto its storage.ObjectLister (adds an fs backend too) instead of the direct S3 client here.

…layer dedup

Read-only audit of the build-cache bucket: groups {scope}/files/{hash}.tar by
content hash across scopes and reports cross-scope duplicate layers, wasted
bytes, and a delete-candidate manifest. Deletes nothing; physical deletion is
a separate operator-gated step that consumes the manifest.

Complements template-gc (e2b-dev#3742): that tool reclaims unreferenced builds by
liveness in the TEMPLATE bucket; this one reports content-duplicate layers in
the BUILD_CACHE bucket. Neither merges the other's data. Pairs with the
opt-in shared cache scope (e2b-dev#3748/e2b-dev#3749) that prevents new duplicates.

Refs e2b-dev#3742 e2b-dev#3748

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants