A general-purpose command-line caching utility that caches the output of arbitrary shell commands. It stores results in a SQLite database and serves cached responses when invoked within the TTL window.
- Cache any shell command output with configurable TTL
- Real-time streaming output for uncached commands
- Interactive TUI cache browser with vim-style navigation
- Automatic cache key generation from command + arguments
- Stale-while-revalidate pattern for instant responses
- Filter cacheable results by exit code
- Check cache status and purge entries programmatically
- Pure Go with no CGO dependencies (SQLite via modernc.org/sqlite)
Requires Go 1.21 or later.
# Clone the repository
git clone https://github.com/semanticart/cache.git
cd cache
# Build and install
make install
# Or install to a custom location
make install PREFIX=~/.localmake build
./cache --helpcache [flags] [--] <command> [args...]
Use -- to separate cache flags from the command to execute.
# Launch interactive cache browser
cache
# Cache an API call for 1 hour (default TTL)
cache -- curl https://api.example.com/data
# Cache with custom TTL (60 seconds)
cache --ttl 60 -- expensive-build-command
# Cache commands that may return non-zero exit codes
cache --cache-status "0 1" -- command-with-acceptable-failures
# Check if a command is cached (exit 0 if cached, 1 if not)
cache --check -- some-command
# Remove a command from cache
cache --purge -- some-command
# Serve stale content while revalidating in background
cache --stale-while-revalidate 300 -- slow-api-call
# Use explicit cache key instead of auto-generated
cache --key my-custom-key -- some-command| Flag | Default | Description |
|---|---|---|
--ttl |
3600 | Cache TTL in seconds |
--cache-status |
"0" | Space-separated list of exit codes to cache |
--stale-while-revalidate |
0 | Serve stale content while revalidating (seconds) |
--check |
false | Return 0 if cached, 1 if not |
--purge |
false | Remove cache entry for given command |
--key |
"" | Explicit cache key (overrides auto-generated) |
When executing uncached commands, cache streams output to your terminal in real-time. This means you see progress immediately rather than waiting for the command to complete. The output is simultaneously captured and stored in the cache.
# Output streams in real-time as the command executes
cache -- npm installStreaming behavior:
- stdout and stderr are interleaved in their original order
- Output appears immediately as the command produces it
- The complete output is still cached for future invocations
- Background revalidation (stale-while-revalidate) runs silently without streaming
When invoked with no arguments, cache launches an interactive TUI for browsing and managing cached entries.
cacheThe browser displays a two-panel interface:
- Left panel: List of cached entries sorted newest to oldest, showing command preview, exit code, duration, age, and output size
- Right panel: Scrollable output of the selected entry
| Key | Action |
|---|---|
j / k |
Navigate up/down through entries (wraps around) |
Ctrl-U / Ctrl-D |
Scroll output viewport half-page up/down |
d |
Delete the selected cache entry |
y |
Copy output to clipboard |
Y |
Copy command to clipboard |
q |
Quit the browser |
- Cache generates a key by hashing the command and arguments
- On cache hit (valid TTL, matching exit code): returns cached output
- On cache miss: executes command, stores result, returns output
- With stale-while-revalidate: serves stale content immediately, updates cache in background
Cache entries are stored in a SQLite database.
The database is stored at /tmp/cache.db by default. This location was chosen for simplicity and because cached command output is typically ephemeral data that doesn't need to persist across system reboots.
The database uses a single table cache_entries with the following structure:
| Column | Type | Description |
|---|---|---|
id |
INTEGER | Primary key (auto-increment) |
cache_key |
TEXT | Unique SHA-256 hash of the command |
command |
TEXT | The original command string |
output |
BLOB | Captured stdout/stderr output |
exit_code |
INTEGER | Command exit code |
duration_ms |
INTEGER | Execution time in milliseconds |
created_at |
INTEGER | Unix timestamp when entry was created |
last_accessed_at |
INTEGER | Unix timestamp of last cache hit |
Cache keys are generated by computing a SHA-256 hash of the command and its arguments joined with null bytes. This ensures:
- Same command with same arguments always produces the same key
- Different argument ordering produces different keys
- Commands like
echo "a b"andecho a bproduce different keys
The database is automatically pruned to 1000 entries maximum. When the limit is exceeded, the oldest entries (by created_at) are removed first.
# Run all checks (format, test, lint, build)
make check
# Or run individually
make fmt
make test
make lint
make build
# Clean build artifacts
make cleanMIT