Caching
SLOzy implements a two-tier caching layer in internal/cache/ for Prometheus query results.
Architecture
Application → Memory Cache (sync.Map) → PostgreSQL (query_cache table)The Service first checks the in-memory cache. On miss, it falls back to the database. Hits are promoted back into memory.
Cache Backend
The query_cache table (migrations/000018) stores:
| Column | Type | Purpose |
|---|---|---|
cache_key | VARCHAR(500) UNIQUE | query:{slo_id}:{time_window}:{sha256} |
query_hash | VARCHAR(64) | SHA256 of query + parameters |
result | JSONB | Cached Prometheus result |
expires_at | TIMESTAMPTZ | TTL-based expiration |
hit_count | INTEGER | Access frequency for hot/cold classification |
is_fresh | BOOLEAN | Fresh vs. calculated data |
Two repository implementations are available: SQLRepository (database/sql) and PgxRepository (pgx/v5 pool).
Configurable TTL
go
type CacheConfig struct {
DefaultTTL time.Duration // default 5 minutes
MaxEntries int // max memory cache entries
CleanupInterval time.Duration // expired entry cleanup frequency
EnableMemoryCache bool
EnableCompression bool // gzip compression for large results
CompressionThreshold int // minimum bytes before compression
EnableWarmup bool
}Invalidation Strategies
| Strategy | Method | Scope |
|---|---|---|
| By key | Invalidate(ctx, cacheKey) | Single entry |
| By SLO ID | InvalidateBySLO(ctx, sloID) | All entries for an SLO |
| By pattern | InvalidateByPattern(ctx, pattern) | Key prefix match |
| By expiration | CleanupExpired(ctx) | All expired entries |
| Full flush | InvalidateAll(ctx) | Entire cache |
LRU eviction runs automatically when MaxEntries is reached.
Statistics
go
type CacheStatistics struct {
TotalEntries int64
TotalHits int64
TotalMisses int64
HitRate float64
MemoryUsage int64 // MB
HotEntriesCount int64 // hit_count > 10
ColdEntriesCount int64 // hit_count <= 10
}API
Routes registered under /api/v1/cache/:
| Endpoint | Description |
|---|---|
GET /statistics | Cache performance metrics |
GET /config | Current configuration (read-only) |
PUT /config | Update configuration (TTL, maxEntries, compression) |
GET /entries | Paginated list of cached entries |
GET /entry/:key | Single entry by key |
POST /entry | Manually create an entry |
DELETE /entry/:key | Delete an entry |
POST /invalidate | Invalidate by key/SLO/pattern/expired/all |
POST /warmup | Preload cache with important queries |
The Cache Management UI is available at /cache in the sidebar.