Skip to content

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:

ColumnTypePurpose
cache_keyVARCHAR(500) UNIQUEquery:{slo_id}:{time_window}:{sha256}
query_hashVARCHAR(64)SHA256 of query + parameters
resultJSONBCached Prometheus result
expires_atTIMESTAMPTZTTL-based expiration
hit_countINTEGERAccess frequency for hot/cold classification
is_freshBOOLEANFresh 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

StrategyMethodScope
By keyInvalidate(ctx, cacheKey)Single entry
By SLO IDInvalidateBySLO(ctx, sloID)All entries for an SLO
By patternInvalidateByPattern(ctx, pattern)Key prefix match
By expirationCleanupExpired(ctx)All expired entries
Full flushInvalidateAll(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/:

EndpointDescription
GET /statisticsCache performance metrics
GET /configCurrent configuration (read-only)
PUT /configUpdate configuration (TTL, maxEntries, compression)
GET /entriesPaginated list of cached entries
GET /entry/:keySingle entry by key
POST /entryManually create an entry
DELETE /entry/:keyDelete an entry
POST /invalidateInvalidate by key/SLO/pattern/expired/all
POST /warmupPreload cache with important queries

The Cache Management UI is available at /cache in the sidebar.