Skip to content

Instantly share code, notes, and snippets.

@camflan
Last active December 10, 2025 21:41
Show Gist options
  • Select an option

  • Save camflan/4d8f58a0c9f08635f941cd01ef761bd8 to your computer and use it in GitHub Desktop.

Select an option

Save camflan/4d8f58a0c9f08635f941cd01ef761bd8 to your computer and use it in GitHub Desktop.
Removes all Django sessions stored in Redis/Valkey
# redis_utils.py
import logging
from functools import lru_cache
from typing import Iterator, Optional
import redis
from django.conf import settings
logger = logging.getLogger(__name__)
DEFAULT_SESSION_PATTERN = "session:*"
WILDCARD_PATTERN = "*"
BATCH_UNLINK_SIZE = 500
@lru_cache(maxsize=1)
def get_default_redis_connection() -> redis.Redis:
"""
Return a cached Redis client using the URL from Django settings.
The connection pool is shared across all callers.
"""
return redis.Redis.from_url(settings.REDIS_URL)
def redis_key_generator(
pattern: str = WILDCARD_PATTERN,
*,
count: int = 1000,
redis_client: Optional[redis.Redis] = None,
) -> Iterator[str]:
"""
Yield Redis keys matching *pattern*.
Parameters
----------
pattern : str, optional
The key glob to match (default '*').
count : int, optional
Number of keys to fetch per SCAN iteration.
redis_client : redis.Redis | None, optional
Existing client to use; otherwise a default connection is created.
Yields
------
str
Redis key names.
"""
r = redis_client or get_default_redis_connection()
for raw_key in r.scan_iter(match=pattern, count=count):
# redis-py 4+ returns bytes; convert to str
yield raw_key.decode("utf-8") if isinstance(raw_key, bytes) else raw_key
def kill_all_sessions(
*, session_key_pattern: str = DEFAULT_SESSION_PATTERN
) -> None:
"""
Delete *all* session keys that match *session_key_pattern*.
The function batches ``UNLINK`` commands to keep network round‑trips low.
"""
logger.info("Removing all sessions matching pattern %s", session_key_pattern)
r = get_default_redis_connection()
batch: list[str] = []
removed_count = 0
for key in redis_key_generator(pattern=session_key_pattern, redis_client=r):
batch.append(key)
if len(batch) >= BATCH_UNLINK_SIZE:
removed_count += r.unlink(*batch)
batch.clear()
if batch: # delete any leftovers
removed_count += r.unlink(*batch)
logger.info(f"Removed {removed_count} {'key' if removed_count == 1 else 'keys'}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment