OWASP / OWASP/Nest

Move Django session backend from database to Redis cache

Open
#4,028 1 comment 0 reactions 1 assignee Claimed by @Shubb07 View on GitHub
enhancement
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.