go-redis guide (Go)

Connect your Go application to a Redis database

go-redis is the Go client for Redis. The sections below explain how to install go-redis and connect your application to a Redis database.

go-redis requires a running Redis server. See here for Redis Open Source installation instructions.

Install

go-redis supports the last two Go versions. You can only use it from within a Go module, so you must initialize a Go module before you start, or add your code to an existing module:

go mod init github.com/my/repo 

Use the go get command to install go-redis/v9:

go get github.com/redis/go-redis/v9 

Connect

The following example shows the simplest way to connect to a Redis server. First, import the go-redis package:

package main  import ( "context" "fmt"  "github.com/redis/go-redis/v9" )   func main() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // no password DB: 0, // use default DB Protocol: 2, })  ctx := context.Background()  err := rdb.Set(ctx, "foo", "bar", 0).Err() if err != nil { panic(err) }  val, err := rdb.Get(ctx, "foo").Result() if err != nil { panic(err) } fmt.Println("foo", val) // >>> foo bar  hashFields := []string{ "model", "Deimos", "brand", "Ergonom", "type", "Enduro bikes", "price", "4972", }  res1, err := rdb.HSet(ctx, "bike:1", hashFields).Result()  if err != nil { panic(err) }  fmt.Println(res1) // >>> 4  res2, err := rdb.HGet(ctx, "bike:1", "model").Result()  if err != nil { panic(err) }  fmt.Println(res2) // >>> Deimos  res3, err := rdb.HGet(ctx, "bike:1", "price").Result()  if err != nil { panic(err) }  fmt.Println(res3) // >>> 4972  res4, err := rdb.HGetAll(ctx, "bike:1").Result()  if err != nil { panic(err) }  fmt.Println(res4) // >>> map[brand:Ergonom model:Deimos price:4972 type:Enduro bikes]  type BikeInfo struct { Model string `redis:"model"` Brand string `redis:"brand"` Type string `redis:"type"` Price int `redis:"price"` }  var res4a BikeInfo err = rdb.HGetAll(ctx, "bike:1").Scan(&res4a)  if err != nil { panic(err) }  fmt.Printf("Model: %v, Brand: %v, Type: %v, Price: $%v\n", res4a.Model, res4a.Brand, res4a.Type, res4a.Price) // >>> Model: Deimos, Brand: Ergonom, Type: Enduro bikes, Price: $4972  rdb.Close() } 

Then connect to localhost on port 6379 and add a context object:

package main  import ( "context" "fmt"  "github.com/redis/go-redis/v9" )   func main() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // no password DB: 0, // use default DB Protocol: 2, })  ctx := context.Background()  err := rdb.Set(ctx, "foo", "bar", 0).Err() if err != nil { panic(err) }  val, err := rdb.Get(ctx, "foo").Result() if err != nil { panic(err) } fmt.Println("foo", val) // >>> foo bar  hashFields := []string{ "model", "Deimos", "brand", "Ergonom", "type", "Enduro bikes", "price", "4972", }  res1, err := rdb.HSet(ctx, "bike:1", hashFields).Result()  if err != nil { panic(err) }  fmt.Println(res1) // >>> 4  res2, err := rdb.HGet(ctx, "bike:1", "model").Result()  if err != nil { panic(err) }  fmt.Println(res2) // >>> Deimos  res3, err := rdb.HGet(ctx, "bike:1", "price").Result()  if err != nil { panic(err) }  fmt.Println(res3) // >>> 4972  res4, err := rdb.HGetAll(ctx, "bike:1").Result()  if err != nil { panic(err) }  fmt.Println(res4) // >>> map[brand:Ergonom model:Deimos price:4972 type:Enduro bikes]  type BikeInfo struct { Model string `redis:"model"` Brand string `redis:"brand"` Type string `redis:"type"` Price int `redis:"price"` }  var res4a BikeInfo err = rdb.HGetAll(ctx, "bike:1").Scan(&res4a)  if err != nil { panic(err) }  fmt.Printf("Model: %v, Brand: %v, Type: %v, Price: $%v\n", res4a.Model, res4a.Brand, res4a.Type, res4a.Price) // >>> Model: Deimos, Brand: Ergonom, Type: Enduro bikes, Price: $4972  rdb.Close() } 

You can also connect using a connection string:

opt, err := redis.ParseURL("redis://<user>:<pass>@localhost:6379/<db>") if err != nil { panic(err) }  client := redis.NewClient(opt) 

After connecting, you can test the connection by storing and retrieving a simple string:

package main  import ( "context" "fmt"  "github.com/redis/go-redis/v9" )   func main() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // no password DB: 0, // use default DB Protocol: 2, })  ctx := context.Background()  err := rdb.Set(ctx, "foo", "bar", 0).Err() if err != nil { panic(err) }  val, err := rdb.Get(ctx, "foo").Result() if err != nil { panic(err) } fmt.Println("foo", val) // >>> foo bar  hashFields := []string{ "model", "Deimos", "brand", "Ergonom", "type", "Enduro bikes", "price", "4972", }  res1, err := rdb.HSet(ctx, "bike:1", hashFields).Result()  if err != nil { panic(err) }  fmt.Println(res1) // >>> 4  res2, err := rdb.HGet(ctx, "bike:1", "model").Result()  if err != nil { panic(err) }  fmt.Println(res2) // >>> Deimos  res3, err := rdb.HGet(ctx, "bike:1", "price").Result()  if err != nil { panic(err) }  fmt.Println(res3) // >>> 4972  res4, err := rdb.HGetAll(ctx, "bike:1").Result()  if err != nil { panic(err) }  fmt.Println(res4) // >>> map[brand:Ergonom model:Deimos price:4972 type:Enduro bikes]  type BikeInfo struct { Model string `redis:"model"` Brand string `redis:"brand"` Type string `redis:"type"` Price int `redis:"price"` }  var res4a BikeInfo err = rdb.HGetAll(ctx, "bike:1").Scan(&res4a)  if err != nil { panic(err) }  fmt.Printf("Model: %v, Brand: %v, Type: %v, Price: $%v\n", res4a.Model, res4a.Brand, res4a.Type, res4a.Price) // >>> Model: Deimos, Brand: Ergonom, Type: Enduro bikes, Price: $4972  rdb.Close() } 

You can also easily store and retrieve a hash:

package main  import ( "context" "fmt"  "github.com/redis/go-redis/v9" )   func main() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // no password DB: 0, // use default DB Protocol: 2, })  ctx := context.Background()  err := rdb.Set(ctx, "foo", "bar", 0).Err() if err != nil { panic(err) }  val, err := rdb.Get(ctx, "foo").Result() if err != nil { panic(err) } fmt.Println("foo", val) // >>> foo bar  hashFields := []string{ "model", "Deimos", "brand", "Ergonom", "type", "Enduro bikes", "price", "4972", }  res1, err := rdb.HSet(ctx, "bike:1", hashFields).Result()  if err != nil { panic(err) }  fmt.Println(res1) // >>> 4  res2, err := rdb.HGet(ctx, "bike:1", "model").Result()  if err != nil { panic(err) }  fmt.Println(res2) // >>> Deimos  res3, err := rdb.HGet(ctx, "bike:1", "price").Result()  if err != nil { panic(err) }  fmt.Println(res3) // >>> 4972  res4, err := rdb.HGetAll(ctx, "bike:1").Result()  if err != nil { panic(err) }  fmt.Println(res4) // >>> map[brand:Ergonom model:Deimos price:4972 type:Enduro bikes]  type BikeInfo struct { Model string `redis:"model"` Brand string `redis:"brand"` Type string `redis:"type"` Price int `redis:"price"` }  var res4a BikeInfo err = rdb.HGetAll(ctx, "bike:1").Scan(&res4a)  if err != nil { panic(err) }  fmt.Printf("Model: %v, Brand: %v, Type: %v, Price: $%v\n", res4a.Model, res4a.Brand, res4a.Type, res4a.Price) // >>> Model: Deimos, Brand: Ergonom, Type: Enduro bikes, Price: $4972  rdb.Close() } 

Use struct tags of the form redis:"<field-name>" with the Scan() method to parse fields from a hash directly into corresponding struct fields:

package main  import ( "context" "fmt"  "github.com/redis/go-redis/v9" )   func main() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // no password DB: 0, // use default DB Protocol: 2, })  ctx := context.Background()  err := rdb.Set(ctx, "foo", "bar", 0).Err() if err != nil { panic(err) }  val, err := rdb.Get(ctx, "foo").Result() if err != nil { panic(err) } fmt.Println("foo", val) // >>> foo bar  hashFields := []string{ "model", "Deimos", "brand", "Ergonom", "type", "Enduro bikes", "price", "4972", }  res1, err := rdb.HSet(ctx, "bike:1", hashFields).Result()  if err != nil { panic(err) }  fmt.Println(res1) // >>> 4  res2, err := rdb.HGet(ctx, "bike:1", "model").Result()  if err != nil { panic(err) }  fmt.Println(res2) // >>> Deimos  res3, err := rdb.HGet(ctx, "bike:1", "price").Result()  if err != nil { panic(err) }  fmt.Println(res3) // >>> 4972  res4, err := rdb.HGetAll(ctx, "bike:1").Result()  if err != nil { panic(err) }  fmt.Println(res4) // >>> map[brand:Ergonom model:Deimos price:4972 type:Enduro bikes]  type BikeInfo struct { Model string `redis:"model"` Brand string `redis:"brand"` Type string `redis:"type"` Price int `redis:"price"` }  var res4a BikeInfo err = rdb.HGetAll(ctx, "bike:1").Scan(&res4a)  if err != nil { panic(err) }  fmt.Printf("Model: %v, Brand: %v, Type: %v, Price: $%v\n", res4a.Model, res4a.Brand, res4a.Type, res4a.Price) // >>> Model: Deimos, Brand: Ergonom, Type: Enduro bikes, Price: $4972  rdb.Close() } 

Close the connection when you're done using a Close() call:

package main  import ( "context" "fmt"  "github.com/redis/go-redis/v9" )   func main() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // no password DB: 0, // use default DB Protocol: 2, })  ctx := context.Background()  err := rdb.Set(ctx, "foo", "bar", 0).Err() if err != nil { panic(err) }  val, err := rdb.Get(ctx, "foo").Result() if err != nil { panic(err) } fmt.Println("foo", val) // >>> foo bar  hashFields := []string{ "model", "Deimos", "brand", "Ergonom", "type", "Enduro bikes", "price", "4972", }  res1, err := rdb.HSet(ctx, "bike:1", hashFields).Result()  if err != nil { panic(err) }  fmt.Println(res1) // >>> 4  res2, err := rdb.HGet(ctx, "bike:1", "model").Result()  if err != nil { panic(err) }  fmt.Println(res2) // >>> Deimos  res3, err := rdb.HGet(ctx, "bike:1", "price").Result()  if err != nil { panic(err) }  fmt.Println(res3) // >>> 4972  res4, err := rdb.HGetAll(ctx, "bike:1").Result()  if err != nil { panic(err) }  fmt.Println(res4) // >>> map[brand:Ergonom model:Deimos price:4972 type:Enduro bikes]  type BikeInfo struct { Model string `redis:"model"` Brand string `redis:"brand"` Type string `redis:"type"` Price int `redis:"price"` }  var res4a BikeInfo err = rdb.HGetAll(ctx, "bike:1").Scan(&res4a)  if err != nil { panic(err) }  fmt.Printf("Model: %v, Brand: %v, Type: %v, Price: $%v\n", res4a.Model, res4a.Brand, res4a.Type, res4a.Price) // >>> Model: Deimos, Brand: Ergonom, Type: Enduro bikes, Price: $4972  rdb.Close() } 

In the common case where you want to close the connection at the end of the function where you opened it, you may find it convenient to use a defer statement right after connecting:

func main() {  rdb := redis.NewClient(&redis.Options{  ...  })  defer rdb.Close()  ... } 

Observability

go-redis supports OpenTelemetry instrumentation. to monitor performance and trace the execution of Redis commands. For example, the following code instruments Redis commands to collect traces, logs, and metrics:

import (  "github.com/redis/go-redis/v9"  "github.com/redis/go-redis/extra/redisotel/v9" )  client := redis.NewClient(&redis.Options{...})  // Enable tracing instrumentation. if err := redisotel.InstrumentTracing(client); err != nil { panic(err) }  // Enable metrics instrumentation. if err := redisotel.InstrumentMetrics(client); err != nil { panic(err) } 

See the go-redis GitHub repo. for more OpenTelemetry examples.

More information

See the other pages in this section for more information and examples. Further examples are available at the go-redis website and the GitHub repository.