Skip to content

go.unbounded_cache

Stability Medium

Detects in-memory caches without size limits that can grow indefinitely.

Unbounded caches cause:

  • Memory exhaustion - Cache grows until OOM
  • GC pressure - Large heaps slow garbage collection
  • Unpredictable scaling - Memory grows with traffic
  • Silent degradation - No errors until crash
// ❌ Before (unbounded)
var cache = make(map[string]interface{})
func Get(key string) interface{} {
return cache[key]
}
func Set(key string, val interface{}) {
cache[key] = val // Grows forever!
}
// ✅ After (bounded LRU)
import "github.com/hashicorp/golang-lru/v2"
var cache, _ = lru.New[string, interface{}](10000)
func Get(key string) (interface{}, bool) {
return cache.Get(key)
}
func Set(key string, val interface{}) {
cache.Add(key, val) // Evicts oldest when full
}
  • Maps used as caches without eviction
  • sync.Map without size limits
  • Growing collections without bounds

Unfault suggests LRU cache libraries:

import "github.com/hashicorp/golang-lru/v2"
// With TTL
import "github.com/hashicorp/golang-lru/v2/expirable"
cache := expirable.NewLRU[string, interface{}](
10000, // max entries
nil, // on evict callback
5 * time.Minute, // TTL
)