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.