Skip to content

Redis (event buffer + user model)

Redis is the online store for the recommender: a per-user event buffer (a sorted set, windowed) and the materialized user model (UserSignals, JSON with a TTL). The AI Engine API reads and writes it on the hot path.

Run locally (Docker)

docker run -d --name redis \
  -p 6379:6379 \
  -v redis_data:/data \
  redis:7 redis-server --appendonly yes
  • --appendonly yes enables persistence so the user model survives a restart.
  • The named volume redis_data keeps the append-only file.

Configure the API

REDIS_URL=redis://localhost:6379/0

If REDIS_URL (or QDRANT_API_URL) is unset, the recsys layer falls back to in-memory fakes, so the API still boots for smoke tests but nothing persists.

Verify

docker exec -it redis redis-cli ping       # PONG
# after some events are ingested:
docker exec -it redis redis-cli keys '*'   # evt:* (buffers) and umodel:* (user models)

What lives in Redis

Key prefix Type Holds
evt:<user_id> sorted set (score = timestamp) the user's recent events, auto-pruned to the window
umodel:<user_id> string (JSON) the materialized UserSignals, with a TTL

A cold or expired user model is rebuilt from the event buffer on the next refresh, so losing umodel:* is not fatal as long as the buffer is intact.

Production

  • Use a managed Redis and set REDIS_URL to it.
  • Enable persistence (AOF or RDB) so the user model is not lost on restart.
  • Co-locate with the API and Qdrant in the same region (the serving path targets sub-second responses).
  • Require auth and TLS; never expose Redis publicly without them.

Kubernetes

Back the append-only file with a PersistentVolumeClaim.

apiVersion: apps/v1
kind: Deployment
metadata: { name: redis }
spec:
  replicas: 1
  selector: { matchLabels: { app: redis } }
  template:
    metadata: { labels: { app: redis } }
    spec:
      containers:
        - name: redis
          image: redis:7
          args: ["redis-server", "--appendonly", "yes"]
          ports: [{ containerPort: 6379 }]
          volumeMounts: [{ name: data, mountPath: /data }]
      volumes:
        - name: data
          persistentVolumeClaim: { claimName: redis-pvc }
---
apiVersion: v1
kind: Service
metadata: { name: redis }
spec:
  selector: { app: redis }
  ports: [{ port: 6379 }]

Or the Bitnami Helm chart:

helm install redis oci://registry-1.docker.io/bitnamicharts/redis

In-cluster, the API uses REDIS_URL=redis://redis:6379/0.