# How to Configure Redis Cache Backend in Gorig Using the Cache Module

> Learn how to configure Redis cache backend in Gorig with the cache module. Set up Redis connection details and instantiate a RedisCache for efficient caching. Get started now.

- Repository: [Jom/gorig](https://github.com/jom-io/gorig)
- Tags: how-to-guide
- Published: 2026-03-04

---

**To configure Redis in Gorig, set the `redis.addr`, `redis.password`, and `redis.db` configuration keys, then instantiate a cache using `cache.New[T](cache.Redis)` which returns a generic `RedisCache[T]` wrapper backed by go-redis/v8.**

Gorig provides a generic, multi-backend cache subsystem that supports in-memory, file-based, SQLite, and Redis storage. When you configure Redis cache backend in Gorig using the cache module, the framework creates a singleton `redis.Client` from the go-redis/v8 library and wraps it in a type-safe `RedisCache[T]` that implements the `Cache[T]` interface.

## Configuration Prerequisites

Gorig reads Redis connection parameters via the configuration helper in [`utils/cofigure/cfg.go`](https://github.com/jom-io/gorig/blob/main/utils/cofigure/cfg.go). The factory function `initRedisCache` in [`cache/cache.redis.go`](https://github.com/jom-io/gorig/blob/main/cache/cache.redis.go) expects three specific keys to build the `redis.Options` struct.

### Required Configuration Keys

| Config Key | Purpose | Default Behavior |
|------------|---------|------------------|
| `redis.addr` | Redis server address in `host:port` format | If empty or omitted, Redis is disabled and initialization is skipped |
| `redis.password` | Password for Redis AUTH command | Empty string (no authentication) |
| `redis.db` | Logical database number as a string | `"0"` (converted to integer 0) |

### Setting Configuration Values

You can provide these values via environment variables or JSON/YAML configuration files. The `configure` package automatically maps environment variables to these keys.

Using environment variables:

```bash
export REDIS_ADDR="127.0.0.1:6379"
export REDIS_PASSWORD="mySecret"
export REDIS_DB="0"

```

Using a YAML configuration file:

```yaml
redis:
  addr: "127.0.0.1:6379"
  password: "mySecret"
  db: "0"

```

## Instantiating the Redis Cache

Once the configuration is loaded—typically during [`bootstrap/startup.go`](https://github.com/jom-io/gorig/blob/main/bootstrap/startup.go) execution—you create a Redis-backed cache through the public API in [`cache/cache.go`](https://github.com/jom-io/gorig/blob/main/cache/cache.go).

### The Factory Function

The generic constructor `cache.New[T any]` selects the backend based on the `cache.Type` argument. Passing `cache.Redis` triggers the Redis initialization path:

```go
import "github.com/jom-io/gorig/cache"

// Create a Redis-backed cache for a custom type
userCache := cache.New[UserProfile](cache.Redis)

```

Internally, this calls `GetRedisInstance[T]` (defined in [`cache/cache.redis.go`](https://github.com/jom-io/gorig/blob/main/cache/cache.redis.go)), which lazily builds the `*redis.Client` if it does not already exist and wraps it in a `*RedisCache[T]`.

### The RedisCache Wrapper

`RedisCache[T]` implements the `Cache[T]` interface, providing methods like `Set`, `Get`, `LPop`, and `RPush`. All values are automatically serialized to JSON before storage and deserialized on retrieval, allowing you to cache any struct that can be marshaled.

## Architecture and Implementation Details

Understanding the internal flow helps debug connection issues and optimize usage.

### Lazy Singleton Initialization

1. **First Call**: When `cache.New[T](cache.Redis)` is invoked, `GetRedisInstance` checks the package-level `redisInstance` variable.
2. **Client Construction**: If `nil`, it calls `initRedisCache`, which reads the three `redis.*` config keys via `configure.GetString` and creates a `redis.Client`.
3. **Reuse**: The client is stored in `redisInstance` for the process lifetime, ensuring all cache instances share a single connection pool.
4. **Disabled State**: If `redis.addr` is empty, the initialization skips client creation, allowing the application to start without Redis.

### Serialization Strategy

All operations in `RedisCache[T]` (see `Set`, `Get`, `RPush` in [`cache/cache.redis.go`](https://github.com/jom-io/gorig/blob/main/cache/cache.redis.go)) use JSON marshaling. This design choice enables the message broker in [`mid/messagex/broker.simple.go`](https://github.com/jom-io/gorig/blob/main/mid/messagex/broker.simple.go) to store complex message structs in Redis lists transparently.

## Practical Code Examples

### Basic Redis Setup with Environment Variables

Ensure your application loads configuration before creating caches:

```go
package main

import (
    "fmt"
    "time"
    "github.com/jom-io/gorig/cache"
)

type Product struct {
    SKU  string  `json:"sku"`
    Price float64 `json:"price"`
}

func main() {
    // Configuration is loaded automatically from env vars or config files
    
    // Create a Redis cache for Product structs
    productCache := cache.New[Product](cache.Redis)
    
    // Store with 5-minute TTL
    productCache.Set("sku:123", Product{SKU: "123", Price: 99.99}, 5*time.Minute)
    
    // Retrieve
    prod, err := productCache.Get("sku:123")
    if err != nil {
        fmt.Println("Cache miss or error:", err)
        return
    }
    fmt.Printf("Cached product: %+v\n", prod)
}

```

### Multi-Level Caching Strategy

Combine in-memory speed with Redis durability using `cache.Tool`:

```go
func NewProductCacheTool() *cache.Tool[Product] {
    // L1: Fast in-memory cache with 1-minute TTL
    memCache := cache.New[Product](cache.Memory, time.Minute)
    
    // L2: Shared Redis cache
    redisCache := cache.New[Product](cache.Redis)
    
    // Loader fetches from database on cache miss
    loader := func(key string) (Product, error) {
        // Database fetch logic here
        return Product{SKU: key, Price: 0.0}, nil
    }
    
    return cache.NewCacheTool[Product](
        context.Background(),
        []cache.Cache[Product]{memCache, redisCache},
        loader,
    )
}

```

### Using Redis as a Message Queue

The `messagex` package uses the Redis cache internally for distributed messaging:

```go
import "github.com/jom-io/gorig/mid/messagex"

// Creates a broker that uses Redis lists (RPush/BRPop) for queuing
broker := messagex.NewSimpleByType(messagex.Redis)

```

This leverages `RedisCache[Message]` to serialize messages as JSON before pushing them to Redis queues.

## Summary

- **Set `redis.addr`** to enable Redis; if omitted, the cache module skips Redis initialization entirely.
- **Use `cache.New[T](cache.Redis)`** to obtain a type-safe `RedisCache[T]` instance that implements the generic `Cache[T]` interface.
- **Configuration is read** from environment variables or config files via [`utils/cofigure/cfg.go`](https://github.com/jom-io/gorig/blob/main/utils/cofigure/cfg.go), supporting `redis.addr`, `redis.password`, and `redis.db`.
- **JSON serialization** is handled automatically by the wrapper, allowing complex Go structs to be stored directly.
- **Singleton pattern** ensures efficient connection reuse through `GetRedisInstance` in [`cache/cache.redis.go`](https://github.com/jom-io/gorig/blob/main/cache/cache.redis.go).
- **Integration** with higher-level components like the message broker in [`mid/messagex/broker.simple.go`](https://github.com/jom-io/gorig/blob/main/mid/messagex/broker.simple.go) works transparently.

## Frequently Asked Questions

### What happens if `redis.addr` is not configured?

If `redis.addr` is empty or undefined, `initRedisCache` in [`cache/cache.redis.go`](https://github.com/jom-io/gorig/blob/main/cache/cache.redis.go) skips client creation entirely. The application starts successfully but Redis caching is unavailable; components attempting to use it may encounter errors or fall back to alternative cache types depending on implementation.

### How does Gorig handle Redis authentication?

The `redis.password` config key is passed directly to the `redis.Options` struct when constructing the client in [`cache/cache.redis.go`](https://github.com/jom-io/gorig/blob/main/cache/cache.redis.go). If left empty, the client connects without authentication. For production environments, set `REDIS_PASSWORD` or the equivalent config file key.

### Can I use multiple Redis databases in the same application?

The current implementation in [`cache/cache.redis.go`](https://github.com/jom-io/gorig/blob/main/cache/cache.redis.go) maintains a single global `redisInstance` configured with one `redis.db` value. To use multiple databases simultaneously, you would need to instantiate separate `redis.Client` instances manually, as the singleton pattern assumes a single shared connection pool.

### Does RedisCache support complex Go types?

Yes. `RedisCache[T]` uses JSON marshaling for all values via the standard `encoding/json` package. As long as your type `T` is JSON-serializable (structs with exported fields, basic types, slices, maps), it can be cached. The wrapper handles serialization in methods like `Set` and deserialization in `Get` automatically.