Introduction: Why Advanced-Level Caching in Go?
In high-load systems built with Go (Golang), data access speed often becomes a bottleneck. A database is not always capable of handling thousands of requests per second without significant delays. Caching is a key tool for reducing database load and speeding up API responses.
At a beginner level, developers often use simple map with mutexes. However, production environments require more advanced solutions: distributed caches (Redis, Memcached) and high-performance in-memory libraries (BigCache, FreeCache). In this article, we will analyze their features, compare performance, and show code examples in Go for each option.
1. Built-in Solutions: sync.Map and BigCache/FreeCache Libraries
1.1. sync.Map — When No External Dependency is Needed
The sync.Map package is a thread-safe map optimized for scenarios where keys are written once and read many times. It does not require read locks, which provides a performance boost.
Usage Example:
package main
import ( "fmt" "sync")
func main() { var cache sync.Map
// Write cache.Store("user:1", "Alice")
// Read if value, ok := cache.Load("user:1"); ok { fmt.Println("Found:", value) }
// Delete cache.Delete("user:1")}Drawbacks: no automatic TTL-based invalidation, no memory limit. Suitable for temporary storage of configurations or rarely changing data.
1.2. BigCache — Fast In-Memory Cache with TTL
BigCache by Allegro is a library that stores data in byte arrays, avoiding GC overhead. It supports TTL and automatic eviction of old entries.
Example:
import ( "github.com/allegro/bigcache/v3" "time")
func main() { cache, _ := bigcache.NewBigCache(bigcache.DefaultConfig(10 * time.Minute))
// Write cache.Set("mykey", []byte("myvalue"))
// Read entry, _ := cache.Get("mykey") println(string(entry))}Pros: minimal GC pressure, high speed (millions of operations per second). Cons: data is stored only as bytes, no support for complex structures without serialization.
1.3. FreeCache — Alternative with Fixed Size
FreeCache is another in-memory library with a configurable cache size. It uses segmentation to reduce lock contention.
import "github.com/coocood/freecache"
func main() { // Cache size — 100 MB cache := freecache.NewCache(100 * 1024 * 1024)
cache.Set([]byte("key"), []byte("value"), 60) // TTL 60 sec got, _ := cache.Get([]byte("key")) println(string(got))}2. Redis — Distributed Caching with Advanced Structures
Redis is the most popular external cache for Go applications. It supports not only strings but also lists, hashes, sets, as well as TTL, Pub/Sub, and transactions.
2.1. Connection and Basic Operations
To work with Redis in Go, the go-redis/redis driver (or redis/v8) is used.
import ( "github.com/go-redis/redis/v8" "context")
var ctx = context.Background()
func main() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", DB: 0, })
// Set with TTL of 10 seconds err := rdb.Set(ctx, "key", "value", 10*time.Second).Err() if err != nil { panic(err) }
val, err := rdb.Get(c