> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/open-webui/open-webui/llms.txt
> Use this file to discover all available pages before exploring further.

# Horizontal Scaling with Redis

> Scale Open WebUI horizontally with Redis-backed sessions and WebSocket support

Open WebUI supports horizontal scaling with Redis for multi-worker and multi-node deployments behind load balancers. This enables high-availability, fault-tolerant production deployments.

## Overview

Redis provides:

* **Distributed Sessions** - Share user sessions across multiple instances
* **WebSocket State** - Synchronized real-time connections across workers
* **Configuration Sync** - Propagate runtime config changes to all nodes
* **Task Coordination** - Distributed task management and pub/sub
* **Rate Limiting** - Centralized rate limit tracking
* **Token Revocation** - Shared JWT token blacklist

## Prerequisites

* Redis server (standalone, cluster, or Sentinel)
* Load balancer (nginx, HAProxy, AWS ALB, etc.)
* Multiple Open WebUI instances

## Redis Configuration

### Standalone Redis

Basic Redis connection:

```bash theme={null}
# Redis connection URL
REDIS_URL=redis://redis-server:6379

# Optional: Redis key prefix (for multi-tenant deployments)
REDIS_KEY_PREFIX=open-webui

# Optional: Socket connection timeout (milliseconds)
REDIS_SOCKET_CONNECT_TIMEOUT=5000

# Optional: Reconnect delay after connection failure (milliseconds)
REDIS_RECONNECT_DELAY=1000
```

### Redis with Authentication

```bash theme={null}
REDIS_URL=redis://:password@redis-server:6379
# Or with username (Redis 6+)
REDIS_URL=redis://username:password@redis-server:6379
```

### Redis with TLS/SSL

```bash theme={null}
REDIS_URL=rediss://redis-server:6380  # Note: rediss:// for TLS
```

### Redis Cluster

For Redis Cluster deployments:

```bash theme={null}
REDIS_URL=redis://node1:6379,node2:6379,node3:6379
REDIS_CLUSTER=true
```

### Redis Sentinel

For high-availability Redis Sentinel:

```bash theme={null}
# Comma-separated Sentinel hosts
REDIS_SENTINEL_HOSTS=sentinel1:26379,sentinel2:26379,sentinel3:26379
REDIS_SENTINEL_PORT=26379

# Master name configured in Sentinel
REDIS_URL=redis://mymaster

# Sentinel retry configuration
REDIS_SENTINEL_MAX_RETRY_COUNT=3
REDIS_RECONNECT_DELAY=1000
```

## Session Management

Redis-backed sessions enable stateless application servers:

```bash theme={null}
# Enable session middleware (required for multi-instance)
ENABLE_STAR_SESSIONS_MIDDLEWARE=true

# Redis URL for session storage
REDIS_URL=redis://redis-server:6379
```

### Session Configuration

```bash theme={null}
# Session cookie settings
WEBUI_SESSION_COOKIE_SAME_SITE=lax  # or 'strict', 'none'
WEBUI_SESSION_COOKIE_SECURE=true  # Require HTTPS

# JWT expiration
JWT_EXPIRES_IN=4w  # 4 weeks, or '7d', '24h', '-1' for never
```

## WebSocket Scaling

Redis enables WebSocket connections across multiple instances:

* Real-time chat updates synchronized
* Task status notifications broadcast
* Multi-node pub/sub messaging

**Automatic** - WebSocket support is automatically enabled when `REDIS_URL` is configured.

## Persistent Configuration

Enable runtime configuration updates across all instances:

```bash theme={null}
# Enable persistent config with Redis sync
ENABLE_PERSISTENT_CONFIG=true
REDIS_URL=redis://redis-server:6379
REDIS_KEY_PREFIX=open-webui
```

Configuration changes via Admin UI are:

1. Saved to database
2. Published to Redis
3. Applied to all running instances

## Docker Compose Example

### Multi-Instance Deployment with Redis

```yaml theme={null}
version: '3'

services:
  # Redis for session and state management
  redis:
    image: redis:7-alpine
    command: redis-server --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis-data:/data
    restart: always
    healthcheck:
      test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
      interval: 10s
      timeout: 3s
      retries: 5

  # PostgreSQL database
  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: openwebui
      POSTGRES_USER: openwebui
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres-data:/var/lib/postgresql/data
    restart: always

  # Open WebUI instance 1
  open-webui-1:
    image: ghcr.io/open-webui/open-webui:main
    environment:
      # Database
      - DATABASE_URL=postgresql://openwebui:${POSTGRES_PASSWORD}@postgres:5432/openwebui
      
      # Redis Configuration
      - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379
      - REDIS_KEY_PREFIX=open-webui
      - ENABLE_STAR_SESSIONS_MIDDLEWARE=true
      - ENABLE_PERSISTENT_CONFIG=true
      
      # Instance identification
      - INSTANCE_ID=instance-1
    volumes:
      - open-webui-data:/app/backend/data
    depends_on:
      - redis
      - postgres
    restart: always

  # Open WebUI instance 2
  open-webui-2:
    image: ghcr.io/open-webui/open-webui:main
    environment:
      - DATABASE_URL=postgresql://openwebui:${POSTGRES_PASSWORD}@postgres:5432/openwebui
      - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379
      - REDIS_KEY_PREFIX=open-webui
      - ENABLE_STAR_SESSIONS_MIDDLEWARE=true
      - ENABLE_PERSISTENT_CONFIG=true
      - INSTANCE_ID=instance-2
    volumes:
      - open-webui-data:/app/backend/data
    depends_on:
      - redis
      - postgres
    restart: always

  # Open WebUI instance 3
  open-webui-3:
    image: ghcr.io/open-webui/open-webui:main
    environment:
      - DATABASE_URL=postgresql://openwebui:${POSTGRES_PASSWORD}@postgres:5432/openwebui
      - REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379
      - REDIS_KEY_PREFIX=open-webui
      - ENABLE_STAR_SESSIONS_MIDDLEWARE=true
      - ENABLE_PERSISTENT_CONFIG=true
      - INSTANCE_ID=instance-3
    volumes:
      - open-webui-data:/app/backend/data
    depends_on:
      - redis
      - postgres
    restart: always

  # Nginx load balancer
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - open-webui-1
      - open-webui-2
      - open-webui-3
    restart: always

volumes:
  redis-data:
  postgres-data:
  open-webui-data:
```

### Nginx Load Balancer Configuration

`nginx.conf`:

```nginx theme={null}
upstream open_webui_backend {
    least_conn;  # Use least connections algorithm
    
    server open-webui-1:8080 max_fails=3 fail_timeout=30s;
    server open-webui-2:8080 max_fails=3 fail_timeout=30s;
    server open-webui-3:8080 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    server_name openwebui.company.com;
    
    # Redirect HTTP to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name openwebui.company.com;
    
    # SSL Configuration
    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    
    # Client upload size
    client_max_body_size 100M;
    
    # WebSocket support
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    
    # Proxy headers
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    
    # Timeouts
    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
    
    location / {
        proxy_pass http://open_webui_backend;
        
        # WebSocket keepalive
        proxy_set_header Connection "upgrade";
        proxy_set_header Upgrade $http_upgrade;
        
        # Disable buffering for streaming responses
        proxy_buffering off;
    }
}
```

## Cloud Deployments

### AWS with Application Load Balancer

```bash theme={null}
# Environment variables for ECS/EKS
DATABASE_URL=postgresql://user:pass@rds-endpoint:5432/openwebui
REDIS_URL=redis://elasticache-endpoint:6379
ENABLE_STAR_SESSIONS_MIDDLEWARE=true
ENABLE_PERSISTENT_CONFIG=true

# ALB handles SSL termination
WEBUI_SESSION_COOKIE_SECURE=true
```

**ALB Configuration**:

* Target Group: Multiple Open WebUI instances
* Health Check: `/health` endpoint
* Stickiness: Not required (Redis sessions)
* WebSocket: Enable WebSocket upgrade headers

### Kubernetes with Ingress

```yaml theme={null}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: open-webui
spec:
  replicas: 3
  selector:
    matchLabels:
      app: open-webui
  template:
    metadata:
      labels:
        app: open-webui
    spec:
      containers:
      - name: open-webui
        image: ghcr.io/open-webui/open-webui:main
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: url
        - name: REDIS_URL
          value: "redis://redis-service:6379"
        - name: ENABLE_STAR_SESSIONS_MIDDLEWARE
          value: "true"
        - name: ENABLE_PERSISTENT_CONFIG
          value: "true"
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: data
          mountPath: /app/backend/data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: open-webui-data
---
apiVersion: v1
kind: Service
metadata:
  name: open-webui
spec:
  selector:
    app: open-webui
  ports:
  - port: 8080
    targetPort: 8080
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: open-webui
  annotations:
    nginx.ingress.kubernetes.io/websocket-services: open-webui
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - openwebui.company.com
    secretName: tls-secret
  rules:
  - host: openwebui.company.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: open-webui
            port:
              number: 8080
```

## Redis High Availability

### Redis Sentinel

For production deployments with automatic failover:

```yaml theme={null}
version: '3'

services:
  redis-master:
    image: redis:7-alpine
    command: redis-server --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis-master:/data

  redis-replica-1:
    image: redis:7-alpine
    command: redis-server --replicaof redis-master 6379 --requirepass ${REDIS_PASSWORD} --masterauth ${REDIS_PASSWORD}
    volumes:
      - redis-replica-1:/data
    depends_on:
      - redis-master

  redis-replica-2:
    image: redis:7-alpine
    command: redis-server --replicaof redis-master 6379 --requirepass ${REDIS_PASSWORD} --masterauth ${REDIS_PASSWORD}
    volumes:
      - redis-replica-2:/data
    depends_on:
      - redis-master

  sentinel-1:
    image: redis:7-alpine
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel.conf:/etc/redis/sentinel.conf
    depends_on:
      - redis-master

  sentinel-2:
    image: redis:7-alpine
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel.conf:/etc/redis/sentinel.conf
    depends_on:
      - redis-master

  sentinel-3:
    image: redis:7-alpine
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel.conf:/etc/redis/sentinel.conf
    depends_on:
      - redis-master

  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    environment:
      - REDIS_URL=redis://mymaster
      - REDIS_SENTINEL_HOSTS=sentinel-1:26379,sentinel-2:26379,sentinel-3:26379
      - REDIS_SENTINEL_PORT=26379
      - REDIS_SENTINEL_MAX_RETRY_COUNT=3
      - ENABLE_STAR_SESSIONS_MIDDLEWARE=true

volumes:
  redis-master:
  redis-replica-1:
  redis-replica-2:
```

`sentinel.conf`:

```
port 26379
sentinel monitor mymaster redis-master 6379 2
sentinel auth-pass mymaster ${REDIS_PASSWORD}
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 10000
```

## Monitoring and Health Checks

### Health Check Endpoint

```bash theme={null}
curl http://localhost:8080/health
```

Returns:

```json theme={null}
{
  "status": "ok",
  "version": "0.3.0"
}
```

### Redis Connection Check

```bash theme={null}
# Test Redis connectivity
redis-cli -h redis-server -p 6379 -a password PING
# Should return: PONG
```

### Monitor Redis Keys

```bash theme={null}
# View session keys
redis-cli -h redis-server -p 6379 -a password KEYS "open-webui:*"

# Monitor real-time commands
redis-cli -h redis-server -p 6379 -a password MONITOR
```

## Troubleshooting

### Redis Connection Failures

**Problem**: Cannot connect to Redis

**Check**:

```bash theme={null}
# Test Redis connectivity
telnet redis-server 6379

# Check Redis logs
docker logs redis-container

# Verify credentials
redis-cli -h redis-server -p 6379 -a password PING
```

### Session Loss

**Problem**: Users logged out frequently

**Check**:

* Redis is running and accessible
* `ENABLE_STAR_SESSIONS_MIDDLEWARE=true` is set
* `REDIS_URL` is correctly configured
* Redis has sufficient memory (check `INFO memory`)

### WebSocket Disconnections

**Problem**: Real-time features not working

**Check**:

* Load balancer supports WebSocket upgrades
* Nginx: `proxy_set_header Upgrade $http_upgrade;`
* ALB: Enable WebSocket support
* Redis pub/sub is functioning

### Configuration Not Syncing

**Problem**: Config changes not applied to all instances

**Check**:

* `ENABLE_PERSISTENT_CONFIG=true` on all instances
* All instances use same `REDIS_URL`
* Redis pub/sub channels working: `redis-cli PUBSUB CHANNELS`

## Performance Tuning

### Redis Optimization

```bash theme={null}
# Increase max connections
maxclients 10000

# Enable persistence for session durability
save 900 1
save 300 10
save 60 10000

# Memory policy
maxmemory 2gb
maxmemory-policy allkeys-lru
```

### Connection Pooling

Open WebUI automatically manages Redis connection pools. Adjust if needed:

```bash theme={null}
# Socket timeout (milliseconds)
REDIS_SOCKET_CONNECT_TIMEOUT=5000

# Reconnect delay after failure (milliseconds)
REDIS_RECONNECT_DELAY=1000
```

## Implementation Details

* Redis utilities: `backend/open_webui/utils/redis.py`
* Session management: `starsessions[redis]==2.2.1`
* Task coordination: `backend/open_webui/tasks.py`
* Configuration sync: `backend/open_webui/config.py:228-287`
* Rate limiting: `backend/open_webui/utils/rate_limit.py`

## Security Best Practices

<Warning>
  **Redis Security:**

  1. **Authentication** - Always use `requirepass` or ACLs
  2. **TLS/SSL** - Use `rediss://` for encrypted connections
  3. **Network Isolation** - Bind Redis to private network only
  4. **Firewall Rules** - Restrict Redis port (6379) access
  5. **Regular Updates** - Keep Redis updated for security patches
  6. **Memory Limits** - Set `maxmemory` to prevent OOM
</Warning>

## Next Steps

* [Observability](/enterprise/observability) - Monitor with OpenTelemetry
* [RBAC](/enterprise/rbac) - Configure access control
* [Enterprise Overview](/enterprise/overview) - Full enterprise features
