What it is
go-redis is the most widely used Redis client for Go, supporting cluster mode, sentinel, pipelining, pub/sub and streams with a context-aware API.
The client covers the full Redis command set with typed methods, plus connection pooling, automatic retries, pipelining and transactions.
Installation
go get github.com/redis/go-redis/v9Getting started
The smallest useful thing you can do with it, and what each part means.
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
PoolSize: 20,
})
defer rdb.Close()
if err := rdb.Set(ctx, "book:42", payload, 10*time.Minute).Err(); err != nil {
return err
}
val, err := rdb.Get(ctx, "book:42").Result()
if errors.Is(err, redis.Nil) {
return ErrCacheMiss // redis.Nil means the key does not exist
}pipe := rdb.Pipeline()
incr := pipe.Incr(ctx, "views:42")
pipe.Expire(ctx, "views:42", time.Hour)
_, err := pipe.Exec(ctx)
fmt.Println(incr.Val()) // results are readable after ExecAdvanced usage
Where the library earns its place over a simpler alternative.
func cached[T any](ctx context.Context, rdb *redis.Client, key string,
ttl time.Duration, load func() (T, error)) (T, error) {
var zero T
if data, err := rdb.Get(ctx, key).Bytes(); err == nil {
var out T
if json.Unmarshal(data, &out) == nil {
return out, nil
}
} else if !errors.Is(err, redis.Nil) {
return zero, err // a real Redis failure, not a miss
}
value, err := load()
if err != nil { return zero, err }
if data, err := json.Marshal(value); err == nil {
rdb.Set(ctx, key, data, ttl) // best effort
}
return value, nil
}Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- redis: nil
- The key does not exist. This is a normal cache miss — compare with errors.Is(err, redis.Nil) rather than treating it as a failure.
- connection pool timeout
- All pooled connections are busy. Raise PoolSize, lower the time each command holds a connection, or check for a slow command such as an unbounded KEYS.
Best practices
- Always check errors.Is(err, redis.Nil) before treating a Get failure as an error.
- Set an explicit TTL on cache keys; unbounded keys eventually fill memory.
- Reuse one client — it pools connections internally; creating one per request defeats that.
- Use pipelining or MGET to collapse multiple round trips.
Background
Why it exists, and what it was reacting to.
Maintained by Vladimir Mihailenco, go-redis became the community default for its complete command coverage and reliable cluster support. It is now published under the redis/go-redis path as an officially recognised client.
