---
title: Cache Models
description: CacheConfig model for Redis, LocMem, and Dummy cache backends
sidebar_label: Cache Models
sidebar_position: 5
---

# Cache Models


Setting `redis_url` automatically creates a Redis cache - no explicit `cache_default` needed.

```python
class MyConfig(DjangoConfig):
    redis_url: str = "redis://localhost:6379/0"  # Auto-creates Redis cache
```

## CacheConfig

Type-safe cache backend configuration with environment-aware smart defaults.

### Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `redis_url` | `str \| None` | `None` | Redis connection URL (`redis://` or `rediss://`) |
| `timeout` | `int` | `300` | Default timeout in seconds (≥0) |
| `max_connections` | `int` | `50` | Maximum Redis connections (≥1) |
| `key_prefix` | `str` | `""` | Cache key prefix |
| `version` | `int` | `1` | Cache key version (≥1) |
| `connection_pool_kwargs` | `dict[str, Any]` | `{}` | Redis connection pool parameters |

### Methods

| Method | Returns | Description |
|--------|---------|-------------|
| `to_django_config(environment, debug)` | `dict[str, Any]` | Convert to Django cache configuration |

### Backend Selection

| Scenario | Backend | Notes |
|----------|---------|-------|
| `redis_url` set | `django_redis.cache.RedisCache` | Production recommended |
| Development (no Redis) | `LocMemCache` | Fast, in-memory, per-process |
| Production (no Redis) | `FileBasedCache` | Creates tmp/ directory |
| Fallback | `DummyCache` | No-op cache |

## Cache Priority

1. **Explicit `cache_default`** - Full control over configuration
2. **Auto from `redis_url`** - Creates RedisCache with defaults (timeout=300, max_connections=50)
3. **Fallback** - LocMemCache (development) or FileBasedCache (production)

## Usage Examples

### Auto Redis (Recommended)

```python
from django_cfg import DjangoConfig

class MyConfig(DjangoConfig):
    secret_key: str = "your-secret-key"
    debug: bool = False
    redis_url: str = "redis://localhost:6379/0"
```

**Generated settings:**
```python
CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://localhost:6379/0',
        'TIMEOUT': 300,
        'KEY_PREFIX': 'my_config',
        'VERSION': 1,
        'OPTIONS': {'CONNECTION_POOL_KWARGS': {'max_connections': 50}}
    }
}
```

### Explicit Redis

```python
from django_cfg import DjangoConfig, CacheConfig

class MyConfig(DjangoConfig):
    secret_key: str = "your-secret-key"
    debug: bool = False
    redis_url: str = "redis://localhost:6379/0"

    cache_default: CacheConfig = CacheConfig(
        redis_url="redis://localhost:6379/0",
        timeout=600,
        key_prefix="myapp",
        max_connections=100
    )
```

### Redis SSL

Use `rediss://` (note double 's') for SSL connections in production.

```python
class MyConfig(DjangoConfig):
    cache_default: CacheConfig = CacheConfig(
        redis_url="rediss://cache.example.com:6380/0",
        timeout=600,
        key_prefix="myapp_prod",
        max_connections=100,
        connection_pool_kwargs={
            'ssl_cert_reqs': 'required',
            'ssl_ca_certs': '/path/to/ca-cert.pem'
        }
    )
```

### LocMem (Development)

Without `redis_url`, uses LocMemCache. Suitable for development and single-server deployments only.

```python
class MyConfig(DjangoConfig):
    debug: bool = True
    cache_default: CacheConfig = CacheConfig(
        timeout=300,
        key_prefix="myapp_dev"
    )
```

### Dummy (Disabled)

Without `cache_default` or `redis_url`, uses DummyCache (no-op).

```python
class MyConfig(DjangoConfig):
    debug: bool = False
    # No cache_default, no redis_url - DummyCache fallback
```


## Multiple Cache Backends

### Default + Sessions Cache

```python
class MyConfig(DjangoConfig):
    secret_key: str = "your-secret-key"
    debug: bool = False

    # Default cache for application data
    cache_default: CacheConfig = CacheConfig(
        redis_url="redis://localhost:6379/0",
        timeout=300,
        key_prefix="myapp"
    )

    # Separate cache for sessions
    cache_sessions: CacheConfig = CacheConfig(
        redis_url="redis://localhost:6379/1",  # Different DB
        timeout=86400,  # 24 hours
        key_prefix="sessions"
    )
```

**Generated Django settings:**
```python
CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://localhost:6379/0',
        'TIMEOUT': 300,
        'KEY_PREFIX': 'myapp',
        'VERSION': 1,
        'OPTIONS': {
            'CONNECTION_POOL_KWARGS': {'max_connections': 50}
        }
    },
    'sessions': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://localhost:6379/1',
        'TIMEOUT': 86400,
        'KEY_PREFIX': 'sessions',
        'VERSION': 1,
        'OPTIONS': {
            'CONNECTION_POOL_KWARGS': {'max_connections': 50}
        }
    }
}

# Sessions backend
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'sessions'
```

## Advanced Redis Configuration

### Connection Pool Settings

```python
cache_default: CacheConfig = CacheConfig(
    redis_url="redis://localhost:6379/0",
    max_connections=100,
    connection_pool_kwargs={
        'socket_connect_timeout': 5,
        'socket_timeout': 5,
        'retry_on_timeout': True,
        'socket_keepalive': True,
    }
)
```

### Redis Sentinel

```python
cache_default: CacheConfig = CacheConfig(
    redis_url="redis://localhost:6379/0",
    connection_pool_kwargs={
        'sentinels': [
            ('sentinel1.example.com', 26379),
            ('sentinel2.example.com', 26379),
        ],
        'service_name': 'mymaster',
    }
)
```

### Redis Cluster

```python
cache_default: CacheConfig = CacheConfig(
    redis_url="redis://node1:6379/0",
    connection_pool_kwargs={
        'startup_nodes': [
            {'host': 'node1.example.com', 'port': 6379},
            {'host': 'node2.example.com', 'port': 6379},
        ],
    }
)
```

## Environment-Specific Configuration

### Using Properties

```python
import os

class MyConfig(DjangoConfig):
    secret_key: str = "your-secret-key"

    @property
    def cache_default(self) -> Optional[CacheConfig]:
        if self._environment == "production":
            return CacheConfig(
                redis_url=os.getenv('REDIS_URL'),
                timeout=600,
                key_prefix="prod",
                max_connections=200
            )
        elif self._environment == "development":
            return CacheConfig(
                # No redis_url - uses LocMemCache
                timeout=60,
                key_prefix="dev"
            )
        return None  # Dummy cache
```

### Using YAML

```yaml
# config.production.yaml
cache_default:
  redis_url: "redis://prod-cache.example.com:6379/0"
  timeout: 600
  key_prefix: "prod"
  max_connections: 200

# config.development.yaml
cache_default:
  timeout: 60
  key_prefix: "dev"
  # No redis_url - auto-selects LocMemCache
```

## Cache Key Versioning

```python
class MyConfig(DjangoConfig):
    secret_key: str = "your-secret-key"
    debug: bool = False

    cache_default: CacheConfig = CacheConfig(
        redis_url="redis://localhost:6379/0",
        key_prefix="myapp",
        version=2  # Increment when cache schema changes
    )
```

**Usage:**

```python
from django.core.cache import cache

# Set with version
cache.set('my_key', 'value', version=2)

# Get with version
value = cache.get('my_key', version=2)

# Different version = cache miss
value = cache.get('my_key', version=1)  # None
```

## Performance Tuning

### Timeout Settings

```python
class MyConfig(DjangoConfig):
    cache_default: CacheConfig = CacheConfig(
        redis_url="redis://localhost:6379/0",
        timeout=300,  # 5 minutes default
    )
```

**Common timeouts:**

- **60s** - Frequently changing data
- **300s (5m)** - Default for most data
- **3600s (1h)** - Semi-static data
- **86400s (24h)** - Very static data

### Connection Pool Size

```python
class MyConfig(DjangoConfig):
    cache_default: CacheConfig = CacheConfig(
        redis_url="redis://localhost:6379/0",
        max_connections=50,  # Adjust based on load
    )
```

**Guidelines:**

- **10-20** - Low traffic (< 1000 req/min)
- **50-100** - Medium traffic (1000-10000 req/min)
- **100-200** - High traffic (> 10000 req/min)

## Security Best Practices

### 1. Use Environment Variables

```python
import os

class MyConfig(DjangoConfig):
    cache_default: CacheConfig = CacheConfig(
        redis_url=os.getenv('REDIS_URL'),
        key_prefix=os.getenv('CACHE_PREFIX', 'myapp')
    )
```

### 2. Enable SSL/TLS

```python
class MyConfig(DjangoConfig):
    cache_default: CacheConfig = CacheConfig(
        redis_url="rediss://cache.example.com:6380/0",  # SSL
        connection_pool_kwargs={
            'ssl_cert_reqs': 'required'
        }
    )
```

### 3. Use Different Databases

```python
class MyConfig(DjangoConfig):
    cache_default: CacheConfig = CacheConfig(
        redis_url="redis://localhost:6379/0"  # DB 0 for cache
    )

    cache_sessions: CacheConfig = CacheConfig(
        redis_url="redis://localhost:6379/1"  # DB 1 for sessions
    )
```

## Troubleshooting

### Redis Connection Errors

**Error:**
```
ConnectionError: Error connecting to Redis
```

**Solution:**
```python
class MyConfig(DjangoConfig):
    cache_default: CacheConfig = CacheConfig(
        redis_url="redis://localhost:6379/0",
        connection_pool_kwargs={
            'socket_connect_timeout': 10,
            'retry_on_timeout': True
        }
    )
```

### Cache Key Too Long

**Error:**
```
ValueError: Cache key too long (max 250 chars)
```

**Solution:**
```python
class MyConfig(DjangoConfig):
    cache_default: CacheConfig = CacheConfig(
        redis_url="redis://localhost:6379/0",
        key_prefix="short"  # Use shorter prefix
    )
```

## See Also

- [**DjangoConfig**](./django-settings) - Base configuration class
- [**Configuration Overview**](./) - Configuration system overview
