Repository navigation
Conversation
Signed-off-by: Will Salt <william@cogna.co>
willejs
force-pushed
the
fix/drop-intermediate-layer-squashes
branch
from
October 16, 2026 08:35
ade4a2b to
69beb61
Compare
|
Thanks for this. We ran into the same issue independently and can confirm the diagnosis. With a synthetic image (a 100k-file base layer plus small layers on top), peak heap in Image.Read grows linearly with layer count: about 0.6 GB at 10 layers and 5.1 GB at 100. Almost all of it is in Tree.Copy / FileNode.Copy from the per-layer squash. An equivalent change on our side (dropping the previous layer's squash once the next one is built) brought the 100-layer case down to about 0.6 GB. SBOMs from the squashed scope were byte-identical before and after across a few dozen real-world images. |
This branch has not been deployed
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.
squashLayersmakes a squash for every layer by copying the one below and merging the layer on top. It keeps all of them, so memory grows with layers × files.We hit this running syft as a DaemonSet. One of our images has 78 layers (~1 GB compressed): a big pip layer near the bottom and ~60 small ones above it. Each small layer gets its own full copy of that big tree, which comes to ~60 copies and 10.7 GB of heap. 85% of it was in
FileTree.Copy.A squashed-scope scan only reads the top layer's squash, so the rest is a waste of memory.
I think this could be related to #233 (and anchore/syft#2942) too.
Change
image.WithImageSquashOnly(ctx)tellsReadto drop each layer's squash once the layer above it is squashed. That leaves at most two trees in memory at a time.LayerFetchExecutor, so it reaches every provider without any constructor changes.all-layersis untouched.ResolveLinkByLayerSquashandLayer.OpenPathFromSquashreturn an error for a dropped layer instead of panicking.Results
Same image, syft v1.52.0, squashed scope:
WithImageSquashOnlyThe SBOM artifacts and files are identical.
Follow-up
If you're happy with this, I will open a Syft PR to set it for squashed scope.
Later on, we could probably look at merging one tree and avoiding the copies, but I am unsure of this right now.