go-redis guide (Go) (original) (raw)

  1. Docs Docs
  2. Develop with Redis
  3. Connect with Redis client API libraries
  4. 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 acontext 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()
}

Usestruct tagsof 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 deferstatement 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.

Connect to the server

Connect your Go application to a Redis database

Connect to Azure Managed Redis

Learn how to authenticate to an Azure Managed Redis (AMR) database

Index and query documents

Learn how to use the Redis query engine with JSON and hash documents.

Index and query vectors

Learn how to index and query vector embeddings with Redis

Vector set embeddings

Index and query embeddings with Redis vector sets

Pipelines and transactions

Learn how to use Redis pipelines and transactions

Probabilistic data types

Learn how to use approximate calculations with Redis.

Error handling

Learn how to handle errors when using go-redis

Production usage

Get your go-redis app ready for production