Caching in Go: Redis, Memcached, and Built-in Solutions

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Caching in Go: Redis, Memcached, and Built-in Solutions



Caching is one of the key tools for improving the performance of web applications and services. In the Go (Golang) ecosystem, developers have access to both external caching systems (Redis, Memcached) and built-in solutions like sync.Map or the bigcache and freecache libraries. In this article, we will analyze the pros and cons of each approach, provide code examples, and help you choose the optimal tool for your project.



1. Built-in Caching: sync.Map and map with Mutex



Go offers basic primitives for creating a cache directly in the application's memory. The simplest way is to use a regular map with a mutex for thread safety.



Example: Simple Thread-Safe Cache



package main

import ( "fmt" "sync" "time")

type Cache struct { mu sync.RWMutex items map[string]interface{}}

func NewCache() *Cache { return &Cache{ items: make(map[string]interface{}), }}

func (c *Cache) Set(key string, value interface{}) { c.mu.Lock() defer c.mu.Unlock() c.items[key] = value}

func (c *Cache) Get(key string) (interface{}, bool) { c.mu.RLock() defer c.mu.RUnlock() val, ok := c.items[key] return val, ok}

func main() { cache := NewCache() cache.Set("user:1", "Alice") val, _ := cache.Get("user:1") fmt.Println(val) // Alice}


For more complex scenarios, Go provides sync.Map — an optimized concurrent map that is better suited for cases where keys are written once and read many times.



When to Use Built-in Caching?

  • Micro-caching (for the duration of a single request or session).
  • Singleton applications without a distributed architecture.
  • Simplicity — no need to set up external services.


Cons: lack of automatic invalidation, limited size (depends on application memory), no persistence.



2. BigCache and FreeCache: Lightweight In-Memory Solutions



The bigcache and freecache libraries solve the problem of limited memory and GC (garbage collection). They use pre-allocated buffers and minimize the load on the Go garbage collector.



Example with BigCache



package main

import ( "fmt" "github.com/allegro/bigcache/v3" "time")

func main() { cache, _ := bigcache.NewBigCache(bigcache.DefaultConfig(10 * time.Minute)) cache.Set("mykey", []byte("myvalue")) val, _ := cache.Get("mykey") fmt.Println(string(val)) // myvalue}


Example with FreeCache



package main

import ( "fmt" "github.com/coocood/freecache")

func main() { cache := freecache.NewCache(100 * 1024) // 100 KB cache.Set([]byte("key"), []byte("value"), 60) // TTL 60 sec val, _ := cache.Get([]byte("key")) fmt.Println(string(val)) // value}


Both libraries support TTL (time to live) and automatic deletion of old entries. BigCache is better for large data volumes (hundreds of gigabytes), FreeCache is better for scenarios with frequent read/write operations.



3. Redis: Distributed Caching for Production



Redis is the most popular choice for caching in Go projects. It runs as a separate server, supports complex data structures, persistence, and clustering.



Connecting Redis in Go



package main

import ( "context" "fmt" "github.com/redis/go-redis/v9")

func main() { ctx := context.Background() rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", DB:

Blogs

Book Recommendations