Hotspots v1.18.0: Compact Storage

Stephen CollinsMay 20, 2026
4 mins

Key Points

What is the difference between prune and compact?

prune removes snapshots for commits that are no longer reachable in your git history — orphans from force-pushes, rebases, or deleted branches. compact operates on snapshots you want to keep but in a more storage-efficient form. They address different problems: prune cleans up dead references, compact shrinks live history.

Does compaction break diff or trends?

No. Level 1 stores deltas on disk but reconstructs full snapshots transparently on read. The diff and trends commands work unchanged against compacted history — they see the same data, just stored more efficiently.

When should I use level 2?

Level 2 is most effective on stable, mature codebases where risk bands (Low/Moderate/High/Critical) change infrequently. On an actively-developed repo it may drop only a handful of extra snapshots after level 1. Use --dry-run first to see the projected savings for your specific repo.

Is compaction reversible?

Level 1 delta conversion is lossless — you can reconstruct any full snapshot by replaying its delta chain. Level 2 deletion is not reversible without re-running hotspots analyze at the dropped commits. Use --dry-run and commit your .hotspots directory to version control before running level 2.

What is the serde default fix?

Older snapshots may be missing fields added in later releases. The compact command loads all snapshots in your history, so any missing non-optional field caused a deserialization failure. This release adds serde(default) to CallGraphMetrics::is_entrypoint, which was the only such field. Snapshot stores from any prior version now load cleanly.

This post was originally published on hotspots.dev.


Hotspots accumulates one snapshot per commit. Over time .hotspots/snapshots/ grows without bound — prune removes snapshots for commits that fell off your branch, but doesn’t help with long-lived main branches. v1.18.0 fixes that.

hotspots compact --level 1

Level 1 converts intermediate snapshots to delta encoding. It keeps the oldest snapshot and the N most-recent snapshots as full representations; everything in between becomes a diff from its chronological predecessor.

hotspots compact --level 1
hotspots compact --level 1 --dry-run   # preview savings without touching files

Results on the hotspots repo itself (45 snapshots):

StageStorageFiles
Before20 MB45 (0 delta)
After level 12.5 MB45 (43 delta, 2 full)

87% reduction. Delta encoding works because most commits change a small fraction of functions — full snapshots duplicate the unchanged majority every time.

hotspots compact --level 2

Level 2 drops snapshots where no function’s risk band changed since the last kept snapshot. Only the oldest and newest are always retained.

hotspots compact --level 2
hotspots compact --level 2 --dry-run

When a delta snapshot’s base is dropped, it’s automatically promoted to a full snapshot so remaining chains stay intact.

Level 2 is most effective on stable codebases. On an actively-developed repo like hotspots, bands change on nearly every commit so level 2 adds modest savings after level 1. On a quiet maintenance repo it can drop 80%+ of remaining snapshots.

--dry-run

Both levels support --dry-run, which measures projected savings without modifying any file:

$ hotspots compact --level 1 --dry-run
Dry-run: would convert 43 snapshot(s) to delta encoding
Estimated storage reduction: 19.0 MB

Upgrading

brew upgrade hotspots
# or
cargo install hotspots-cli

Full release notes and source at github.com/Stephen-Collins-tech/hotspots.