How Mole's Caching System Speeds Up Disk Analysis
Mole's caching system stores filesystem scan results in ~/.cache/mole using xxHash-64 keyed binary files, validating them for up to 7 days while detecting directory modifications to avoid unnecessary rescans.
Mole is an open-source disk analysis tool by tw93/Mole that builds detailed views of filesystem trees, large files, and storage totals. Because full directory walks can be expensive on large drives, Mole's caching system persists per-directory results and reuses them when possible. The implementation lives primarily in cmd/analyze/cache.go, with integration logic spread across cmd/analyze/scanner.go and cmd/analyze/main.go.
Cache Storage Location and Structure
Where Mole Stores Cache Files
Mole creates a dedicated cache directory at ~/.cache/mole on first run. The getCacheDir() function in cmd/analyze/cache.go (lines 65-71) ensures this directory exists before any write operations.
Each scanned path receives its own cache file named <hash>.cache, where the hash is a xxHash-64 of the absolute path string. The getCachePath() function (lines 78-84) generates these filenames consistently.
Additionally, Mole maintains an overview.json file in the same directory for quick size lookups of top-level folders. This is managed separately from the per-path caches.
The Cache Entry Data Structure
Each .cache file stores a serialized cacheEntry struct defined in cmd/analyze/cache.go:
type cacheEntry struct {
Entries []dirEntry // all scanned directories
LargeFiles []fileEntry // files > threshold
TotalSize int64 // bytes of everything under the path
TotalFiles int64 // file count
ModTime time.Time // modification time of the directory at scan time
ScanTime time.Time // when the scan finished
}
The saveCacheToDisk() function (lines 57-85) writes this structure using Go's gob encoding for fast binary serialization.
Cache Validation and Expiration Logic
Mole's caching system implements a multi-layered validation strategy in loadCacheFromDisk() (lines 8-36) to balance performance with accuracy.
The 7-Day Age Limit
By default, any cache older than 7 days is automatically rejected, regardless of directory state. This hard limit prevents displaying stale data from long-obsolete scans. The check compares ScanTime against the current time, rejecting entries where scanAge > 7*24h.
Directory Modification Detection
If the cache is younger than 7 days, Mole checks whether the directory has changed since the scan. It compares the current directory ModTime against the ModTime stored in the cache entry.
If the current modification time is newer than the cached value, the cache is usually invalid.
Grace Windows and Reuse Policies
To prevent excessive invalidations from minor, rapid changes, Mole applies two configurable windows defined in cmd/analyze/constants.go (lines 20-21):
cacheModTimeGrace: A tolerance period for directory modifications. If the directory changed within this grace period, the cache remains valid.cacheReuseWindow: If this is set and the scan age is within this window, Mole reuses the cache even if the directory modified time suggests change.
The validation logic in loadCacheFromDisk() implements this cascade:
if info.ModTime().After(entry.ModTime) {
if cacheModTimeGrace <= 0 || info.ModTime().Sub(entry.ModTime) > cacheModTimeGrace {
if cacheReuseWindow <= 0 || scanAge > cacheReuseWindow {
return nil, fmt.Errorf("cache expired: directory modified")
}
}
}
Performance Optimizations
Stale Cache for Instant UI Rendering
When starting the TUI mode via runTUIMode() in cmd/analyze/main.go (line 66), Mole spawns prefetchOverviewCache() to load data immediately. The loadStaleCacheFromDisk() function (lines 38-55) implements a "stale-while-revalidate" pattern:
- It ignores the strict 7-day age limit and modification checks
- It only verifies the cache is younger than
staleCacheTTL(approximately 5 seconds) - If valid, the UI renders instantly while a background scan refreshes the data
This ensures users see a directory tree immediately, even if it's slightly outdated, rather than waiting for a full filesystem walk.
Overview Snapshots for Quick Size Lookups
For the overview mode that lists top-level directories, Mole maintains a separate overview.json snapshot. The loadStoredOverviewSize() function (lines 6-11) checks this JSON map, which stores size and updated timestamps.
If the snapshot is younger than overviewCacheTTL (approximately 30 minutes), Mole returns the stored size without touching the per-path cache or scanning the directory. After a fresh scan completes, storeOverviewSize() (lines 15-30) automatically updates this snapshot.
How the Analyze Command Integrates Caching
The caching system is tightly integrated into the analysis workflow across three main components:
-
Prefetched Loading: When
runTUIMode()starts incmd/analyze/main.go(lines 65-70), it immediately callsprefetchOverviewCache()to load any available cached data before the UI renders. -
Scan-Time Resolution: In
cmd/analyze/scanner.go, the scanner first attemptsloadCacheFromDisk(path)(lines 351-356).- Cache Hit: The UI populates instantly with the cached
cacheEntrydata. - Cache Miss: The scanner performs a full filesystem walk, then calls
saveCacheToDisk()(lines 57-85) to persist the new results.
- Cache Hit: The UI populates instantly with the cached
-
Overview Updates: After a successful scan, the system calls
storeOverviewSize()(lines 61-62) to update theoverview.jsonsnapshot, ensuring subsequent top-level listings remain fast.
Clearing and Invalidating the Cache
Users can clear Mole's caching system through several methods:
Manual deletion of the entire cache directory:
rm -rf "${HOME}/.cache/mole"
Using Mole's built-in purge command:
mo purge
This executes the bin/purge.sh script (lines 102-114), which specifically removes cache files while preserving the directory structure.
Update-triggered clearing: When running mo update or reinstalling Mole, the installation process ensures a clean cache directory to prevent version incompatibilities.
Summary
- Mole's caching system stores disk analysis results in
~/.cache/moleusing xxHash-64 keyed binary files encoded with Go'sgobformat. - Each cache entry contains the full directory tree, large file lists, totals, and modification timestamps, defined in the
cacheEntrystruct incmd/analyze/cache.go. - Validation logic rejects caches older than 7 days or those where the directory has been modified outside the grace window, with configurable tolerance via
cacheModTimeGraceandcacheReuseWindow. - Performance features include stale-cache loading for instant UI rendering (5-second tolerance) and an
overview.jsonsnapshot for 30-minute fast size lookups of top-level directories. - The analyze command integrates caching via
loadCacheFromDisk()incmd/analyze/scanner.go, falling back to full scans that automatically persist viasaveCacheToDisk(). - Users can invalidate caches manually, via
mo purge, or through updates that clean the~/.cache/moledirectory.
Frequently Asked Questions
Where does Mole store its cache files?
Mole stores all cache files in the ~/.cache/mole directory. The getCacheDir() function in cmd/analyze/cache.go creates this directory automatically if it doesn't exist. Individual scan results are stored as <hash>.cache files where the hash is a xxHash-64 of the absolute path, while overview snapshots live in overview.json.
How long does Mole's cache remain valid?
By default, Mole's cache remains valid for up to 7 days. However, the cache also becomes invalid immediately if the directory's modification time changes outside the configured grace window (cacheModTimeGrace). Additionally, the overview snapshot used for quick size lookups expires after approximately 30 minutes (overviewCacheTTL), while stale caches used for instant UI rendering last only about 5 seconds (staleCacheTTL).
Can I force Mole to ignore the cache?
While there is no public command-line flag exposed in the current version, you can force Mole to ignore the cache by removing the specific cache file before running the analysis. Locate the cache file by computing the xxHash-64 of your target path, then delete ${HOME}/.cache/mole/<hash>.cache. Alternatively, running mo purge clears all caches, ensuring the next analysis performs a fresh scan.
What happens if I modify files while Mole is running?
If files are modified while Mole is running, the stale cache mechanism ensures the UI remains responsive. When the TUI launches, it first loads any available cache (even if slightly outdated) to render the initial view instantly. A background scan then refreshes the data asynchronously. For subsequent runs, the loadCacheFromDisk() function detects the directory modification via ModTime comparison and invalidates the cache unless the change falls within the grace window, ensuring you don't see stale data for long.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →