# How to Configure Grok2API to Use Redis as Its Runtime Store

> Configure Grok2API to use Redis as its runtime store by updating config yaml. Learn how to connect and enable distributed state for your gateway instances.

- Repository: [Chenyme/grok2api](https://github.com/chenyme/grok2api)
- Tags: how-to-guide
- Published: 2026-07-16

---

**Set `runtimeStore.driver` to `redis` in your [`config.yaml`](https://github.com/chenyme/grok2api/blob/main/config.yaml) and provide connection details including `address`, `database` (0–1024), and `keyPrefix` (1–128 characters) to enable distributed state across multiple gateway instances.**

Grok2API, the open-source gateway for xAI's Grok models, uses a runtime store to manage transient data such as rate limits, concurrency leases, and distributed locks. By default, the service runs with an in-memory implementation, but production deployments requiring horizontal scaling must configure Redis as the backend store. This guide explains how to configure the `chenyme/grok2api` repository to use Redis for shared state across multiple gateway instances.

## Edit the YAML Configuration File

Runtime store configuration resides in the `runtimeStore` section of your [`config.yaml`](https://github.com/chenyme/grok2api/blob/main/config.yaml) file (see [`config.example.yaml`](https://github.com/chenyme/grok2api/blob/main/config.example.yaml) for the complete reference). To switch from the default `memory` driver to Redis, set the `driver` field to `redis` and populate the nested `redis` configuration block.

```yaml
runtimeStore:
  driver: redis
  redis:
    address: "127.0.0.1:6379"
    username: ""
    password: ""
    database: 0
    keyPrefix: "grok2api:"
    tls: false

```

The configuration schema is defined in [`backend/internal/infra/config/config.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/infra/config/config.go) within the `RuntimeStoreConfig` struct. The `address` field accepts standard Redis host:port notation, while `database` specifies the Redis DB index (0–1024). The `keyPrefix` parameter ensures all runtime keys are namespaced, preventing collisions when multiple services share the same Redis instance.

## Validation Requirements

Grok2API validates Redis configuration during startup through the `Config.Validate()` method in [`backend/internal/infra/config/config.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/infra/config/config.go) (lines 36–50). The validation enforces three critical constraints:

- **Address**: Must be non-empty
- **Database**: Must be an integer between 0 and 1024
- **KeyPrefix**: Must contain between 1 and 128 characters

If any validation fails, the service logs a fatal error and exits before attempting to connect. This prevents runtime failures from misconfigured connection strings.

## Runtime Store Initialization

When `driver` is set to `redis`, the backend initializes the store by calling `redis.Open(ctx, cfg)` in [`backend/internal/infra/runtime/redis/store.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/infra/runtime/redis/store.go) (lines 64–80). This function performs the following steps:

1. Creates a `go-redis/v9` client using the provided credentials
2. Pings the Redis server to verify connectivity
3. Sets a default lease duration if not explicitly configured
4. Returns a `Store` instance implementing the runtime store interface

The `Store` type exposes methods including `PublishSettingsChanged` and `ListenSettingsChanges` (lines 88–100), which enable hot-reloading of configuration across all connected instances via Redis Pub/Sub.

## Programmatic Configuration

For deployments that construct configuration programmatically, create a `config.RuntimeStoreConfig` struct and pass it to `redis.Open()`:

```go
import (
    "context"
    "github.com/chenyme/grok2api/backend/internal/infra/config"
    "github.com/chenyme/grok2api/backend/internal/infra/runtime/redis"
)

cfg := config.Config{
    RuntimeStore: config.RuntimeStoreConfig{
        Driver: "redis",
        Redis: config.RedisRuntimeConfig{
            Address:   "redis.internal:6379",
            Username:  "",
            Password:  "s3cr3t",
            Database:  2,
            KeyPrefix: "grok2api:",
            TLS:       true,
        },
    },
}

store, err := redis.Open(context.Background(), redis.Config{
    Address:   cfg.RuntimeStore.Redis.Address,
    Username:  cfg.RuntimeStore.Redis.Username,
    Password:  cfg.RuntimeStore.Redis.Password,
    Database:  cfg.RuntimeStore.Redis.Database,
    KeyPrefix: cfg.RuntimeStore.Redis.KeyPrefix,
    TLS:       cfg.RuntimeStore.Redis.TLS,
})
if err != nil {
    log.Fatalf("failed to connect Redis: %v", err)
}
defer store.Close()

```

## Architecture Overview

Switching to Redis transforms the runtime store from a local singleton into a distributed service. The implementation in [`backend/internal/infra/runtime/redis/store.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/infra/runtime/redis/store.go) wraps the Redis client and executes **Lua scripts** for atomic operations including rate limiting, lease acquisition, and distributed lock management.

All gateway instances sharing the same `keyPrefix` and Redis endpoint automatically coordinate state:

- **Rate limiting counters** increment atomically across the cluster
- **Sticky routing information** persists regardless of which instance handles the request
- **Device OAuth sessions** remain valid when requests bounce between gateways
- **Distributed locks** prevent race conditions during configuration updates

The Pub/Sub mechanism broadcasts settings changes immediately, ensuring configuration consistency without requiring instance restarts.

## Summary

- Configure Redis by setting `runtimeStore.driver` to `redis` in [`config.yaml`](https://github.com/chenyme/grok2api/blob/main/config.yaml)
- Provide connection details including `address`, `database` (0–1024), and `keyPrefix` (1–128 characters)
- Validation occurs in [`backend/internal/infra/config/config.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/infra/config/config.go) before startup
- The store initializes via `redis.Open()` in [`backend/internal/infra/runtime/redis/store.go`](https://github.com/chenyme/grok2api/blob/main/backend/internal/infra/runtime/redis/store.go)
- Redis enables horizontal scaling through Lua-backed atomic operations and Pub/Sub synchronization

## Frequently Asked Questions

### What happens if the Redis connection fails during startup?

The `redis.Open()` function returns an error that causes the gateway to exit with a fatal log message. As implemented in [`backend/cmd/grok2api/main.go`](https://github.com/chenyme/grok2api/blob/main/backend/cmd/grok2api/main.go), the service requires a functional runtime store to manage rate limits and sessions, so it cannot degrade gracefully to memory mode once Redis is configured.

### Can I use Redis Sentinel or Cluster mode with Grok2API?

The current implementation in [`store.go`](https://github.com/chenyme/grok2api/blob/main/store.go) uses a standard `go-redis/v9` client configured with a single `address`. For Sentinel or Cluster deployments, you would need to modify the `redis.Open()` function to accept sentinel or cluster client options, as the current configuration schema only supports single-node Redis instances.

### How does the keyPrefix affect shared state?

The `keyPrefix` parameter prefixes every key stored in Redis, acting as a namespace. All instances sharing the same prefix and Redis database see the same runtime state. If you run multiple independent Grok2API deployments against the same Redis server, use distinct prefixes (e.g., `grok2api-prod:` and `grok2api-staging:`) to isolate their data.

### Does Grok2API support Redis TLS authentication?

Yes, set `tls: true` in the Redis configuration block. The `redis.Open()` function passes the TLS flag to the underlying `go-redis/v9` client, enabling encrypted connections. Combine this with the `username` and `password` fields for authenticated, encrypted connections to managed Redis services.