Move Django session backend from database to Redis cache
- Dominant language
- Python
- Stars
- 451
- Forks
- 702
- Avg merge
- 22h 59m
- Merged PRs (30d)
- 91
Description
**Describe the bug**
Django sessions are currently stored in PostgreSQL (the default `django.contrib.sessions.backends.db` engine) even though Redis is already running and configured as the cache backend via `django_redis`.
This means every authenticated request triggers a database query just to read/write the session, adding unnecessary load to PostgreSQL. Since Redis is already available and serving cache data, sessions should leverage it for significantly faster lookups.
In `backend/settings/base.py`, `SESSION_ENGINE` is not explicitly set, so Django defaults to database-backed sessions:
```python
# These session settings exist (lines 31-35):
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_NAME = "nest.session-id"
SESSION_COOKIE_SAMESITE = "Lax"
SESSION_COOKIE_SECURE = True
# But SESSION_ENGINE is never defined — defaults to "django.contrib.sessions.backends.db"
```
Meanwhile, Redis is already fully configured:
```python
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": f"redis://:{REDIS_PASSWORD}@{REDIS_HOST}:6379",
...
}
}
```
**To Reproduce**
1. Inspect `backend/settings/base.py` — no `SESSION_ENGINE` is defined
2. Django defaults to `django.contrib.sessions.backends.db` (PostgreSQL)
3. Every authenticated request (e.g., admin panel at `/a/`) triggers a DB query to `django_session` table
4. Meanwhile, Redis is already running and configured but only used for caching
**Expected behavior**
Sessions should be stored in Redis (which is already running) to avoid unnecessary database queries and improve response times for authenticated requests.
**Are you going to work on fixing this?**
- [x] Yes
- [ ] No
**Describe the solution you'd like**
Add `SESSION_ENGINE` to `backend/settings/base.py` to use Redis-backed sessions:
```python
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
```
**Option A — Cache-only sessions (recommended for performance):**
```python
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
```
- Sessions are stored exclusively in Redis
- Fastest option — no DB queries for session operations
- Tradeoff: If Redis restarts, all sessions are lost (users need to re-login)
**Option B — Cache + DB fallback (safer):**
```python
SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
SESSION_CACHE_ALIAS = "default"
```
- Reads from Redis first (fast), falls back to DB if cache miss
- Writes to both Redis and DB
- Survives Redis restarts, but slightly slower writes
Given that Nest's sessions are primarily for the admin panel and GitHub OAuth login (not long-lived user data), **Option A** is likely sufficient.
**Describe alternatives you've considered**
- **Keep database sessions (current)**: Simple but adds unnecessary DB load, especially as concurrent users grow with multi-worker Gunicorn (#4027)
- **Signed cookie sessions** (`django.contrib.sessions.backends.signed_cookies`): No server-side storage needed, but limited by cookie size (4KB) and can't be server-side invalidated
**Additional context**
- This pairs well with the Gunicorn multi-worker configuration (#4027) — with multiple workers handling concurrent requests, reducing per-request DB queries becomes even more important.
- The `django_redis` package is already installed and configured, so no new dependencies are needed.
- The change is a 2-line addition to `backend/settings/base.py`.
Contributor guide
Assessment
This issue has not been assessed yet.