Cache Configuration Guide
Overview
Section titled “Overview”FinFocus includes an optional BoltDB-backed cache that stores cost query results locally. When enabled, repeated runs against the same resources return results from disk instead of making live plugin calls, cutting latency significantly for large stacks.
The cache is disabled by default. You opt in by setting a positive TTL value.
Target Audience: End Users, DevOps Engineers, CI/CD Operators
Prerequisites:
- FinFocus CLI installed
- Pulumi project configured with at least one plugin
Learning Objectives:
- Enable and configure the cost cache
- Understand cache key structure and TTL behaviour
- Disable or invalidate the cache when needed
- Troubleshoot stale or corrupted cache entries
Estimated Time: 5 minutes
Table of Contents
Section titled “Table of Contents”Quick Start
Section titled “Quick Start”Enable the cache in under 2 minutes.
Step 1: Add Cache Config
Section titled “Step 1: Add Cache Config”Edit ~/.finfocus/config.yaml (global) or your project’s .finfocus/config.yaml:
# yaml-language-server: $schema=https://rshade.github.io/finfocus/schemas/config.jsoncost: cache: enabled: true ttl_seconds: 3600 # 1 hour; 0 disables the cache directory: "" # empty = auto-resolveStep 2: Run a Cost Command
Section titled “Step 2: Run a Cost Command”finfocus cost projected --pulumi-json plan.jsonStep 3: Run Again and See Cache Hits
Section titled “Step 3: Run Again and See Cache Hits”finfocus cost projected --pulumi-json plan.jsonExpected Output (second run):
RESOURCE ADAPTER MONTHLY CURRENCY NOTESaws:ec2/instance:Instance aws-public (cached) $73.00 USD t3.mediumaws:rds/instance:DbInstance aws-public (cached) $146.00 USD db.t3.mediumThe (cached) suffix on the Adapter column confirms results came from disk.
Configuration Reference
Section titled “Configuration Reference”File Location
Section titled “File Location”Cache settings belong under the cost.cache key in either:
~/.finfocus/config.yaml- global default, applies to all projects$PROJECT/.finfocus/config.yaml- project-local override (takes precedence)
Configuration Options
Section titled “Configuration Options”| Option | Type | Default | Required | Description |
|---|---|---|---|---|
enabled | boolean | false | No | Master switch. false disables caching entirely. |
ttl_seconds | integer | 3600 | No | Seconds until a cached entry expires. 0 disables. |
directory | string | "" | No | Explicit cache directory path. Empty = auto. |
Note: When
enabled: trueis set without specifyingttl_seconds, the default of 3600 seconds (1 hour) applies automatically. Settingttl_seconds: 0disables expiration even whenenabled: true.
CLI Flag
Section titled “CLI Flag”Override the TTL for a single run without changing config:
finfocus cost projected --cache-ttl 1800 --pulumi-json plan.json# 0 disables the cache for this runfinfocus cost projected --cache-ttl 0 --pulumi-json plan.jsonEnvironment Variables
Section titled “Environment Variables”| Variable | Description | Example |
|---|---|---|
FINFOCUS_CACHE_TTL | Override TTL in seconds (integer) | 7200 |
FINFOCUS_CACHE_TTL_SECONDS | Fallback alias for FINFOCUS_CACHE_TTL | 7200 |
FINFOCUS_CACHE_DIR | Override cache directory | /tmp/finfocus-cache |
Precedence (highest to lowest): --cache-ttl flag > FINFOCUS_CACHE_TTL env >
cost.cache.ttl_seconds config > built-in default (3600 when enabled).
Cache Directory Resolution
Section titled “Cache Directory Resolution”When directory is empty, FinFocus resolves the cache location in this order:
FINFOCUS_CACHE_DIRenvironment variablecost.cache.directoryconfig value- Project-local
.finfocus/cache/(when aPulumi.yamlis found) ~/.finfocus/cache/
The database file is always named cache.db inside the resolved directory.
How the Cache Works
Section titled “How the Cache Works”Storage Backend
Section titled “Storage Backend”The cache uses BoltDB, a single-file embedded key-value store. No external database process is required.
~/.finfocus/cache/└── cache.db # Single BoltDB file containing all cached dataBuckets and Key Structure
Section titled “Buckets and Key Structure”The database contains three buckets, one per cost operation:
| Bucket | Key Format | Scope |
|---|---|---|
projected | projected/{provider}/{type}/{region}/{sku} | Per resource |
actual | actual/{adapter}/{start}/{end}/{groupBy}/... | Per query |
recommendations | recommendations/{provider}/{type}/{region} | Per resource |
Projected costs are cached per individual resource, so changing one resource only invalidates that resource’s entry. Actual cost queries are cached as a whole (the full query including time range and filters forms the key).
TTL and Expiration
Section titled “TTL and Expiration”- Expiration is lazy: entries are checked on read and discarded if past their TTL.
- A startup cleanup pass removes all expired entries when the cache is opened.
- Setting
ttl_seconds: 0orenabled: falsedisables the cache; no file is written.
Graceful Degradation
Section titled “Graceful Degradation”Cache failures never block cost operations. If the cache file cannot be opened or a read fails, FinFocus logs a warning and continues with live plugin calls. If the file is corrupted, FinFocus automatically deletes and recreates it.
Commands That Use the Cache
Section titled “Commands That Use the Cache”cost projected, cost actual, cost recommendations, cost estimate, overview,
and analyzer serve all participate in caching when enabled.
Examples
Section titled “Examples”Example 1: Enable Cache for a Project
Section titled “Example 1: Enable Cache for a Project”Use Case: Speed up repeated cost projected runs during active development.
Configuration (in $PROJECT/.finfocus/config.yaml):
cost: cache: enabled: true ttl_seconds: 3600Usage:
# First run - fetches from plugins, populates cachefinfocus cost projected --pulumi-json plan.json
# Second run - returns cached resultsfinfocus cost projected --pulumi-json plan.jsonExample 2: Override TTL per Run
Section titled “Example 2: Override TTL per Run”Use Case: Force fresh data for a specific run without changing global config.
# Bypass cache entirely for this runfinfocus cost projected --cache-ttl 0 --pulumi-json plan.json
# Use a shorter TTL of 5 minutes for this runfinfocus cost projected --cache-ttl 300 --pulumi-json plan.jsonExample 3: CI/CD with Cache Disabled
Section titled “Example 3: CI/CD with Cache Disabled”Use Case: Always fetch live pricing data in automated pipelines.
# In your CI pipeline scriptfinfocus cost projected --cache-ttl 0 --pulumi-json plan.jsonAlternatively, set the environment variable for the entire job:
env: FINFOCUS_CACHE_TTL: "0"steps: - run: finfocus cost projected --pulumi-json plan.jsonTroubleshooting
Section titled “Troubleshooting”Issue: Cache entries never expire
Section titled “Issue: Cache entries never expire”Symptoms: Running with fresh plugin data still shows (cached) results.
Cause: TTL is larger than expected, or the system clock changed.
Solution: Force a fresh run by passing --cache-ttl 0, then restore the desired TTL:
finfocus cost projected --cache-ttl 0 --pulumi-json plan.jsonIssue: Stale data after resource changes
Section titled “Issue: Stale data after resource changes”Symptoms: Cost output does not reflect a resource type or SKU change.
Cause: Projected cost cache is keyed by provider/type/region/sku. If you changed
an input that is part of the key (e.g., instance type), the old key is no longer matched
and the new key is a cache miss - fresh data is fetched automatically. If you changed a
field that is NOT part of the key (e.g., tags), the cached entry is reused.
Solution: Use --cache-ttl 0 for a single run or reduce ttl_seconds in config.
Issue: Corrupted cache file
Section titled “Issue: Corrupted cache file”Symptoms: Errors mentioning bbolt, unexpected EOF, or invalid database.
Cause: The cache.db file was corrupted (e.g., process killed mid-write).
Solution: FinFocus auto-recovers by deleting and recreating the file. If auto-recovery does not trigger, delete the file manually:
rm ~/.finfocus/cache/cache.dbIssue: Cache directory permission denied
Section titled “Issue: Cache directory permission denied”Symptoms: Warning like failed to open cache: permission denied.
Solution: Check ownership of the cache directory:
ls -la ~/.finfocus/cache/# Fix ownership if neededchown -R $USER ~/.finfocus/cache/See Also
Section titled “See Also”Related Guides:
- Budget Configuration Guide - Set spending limits and alerts
- Recommendations Guide - Cost optimization suggestions
- Troubleshooting Guide - General issue resolution
CLI Reference:
- cost projected - Estimate projected costs
- cost actual - Fetch historical costs
- cost recommendations - Display recommendations
Configuration Reference:
- Cache Configuration - Complete option reference
Last Updated: 2026-02-17 FinFocus Version: v0.3.1 Feedback: Open an issue to improve this guide