Session Backends¶
CRUDAdmin provides flexible, scalable session management with multiple backend options. This guide covers how to configure and use different session backends for optimal performance and functionality across development, staging, and production environments.
Prerequisites¶
Before configuring session backends, ensure you have:
- CRUDAdmin instance created and configured (see Basic Configuration)
- Understanding of your deployment environment requirements
- Optional: Redis or Memcached installed for production backends
Backend Overview¶
CRUDAdmin supports five session backend types, each optimized for different use cases:
Backend | Performance | Scalability | Persistence | Admin Visibility | Dependencies | Use Case |
---|---|---|---|---|---|---|
Memory | Excellent | Single node | No | No | None | Development, testing |
Redis | Excellent | Horizontal | Yes* | No | Redis server | Production, high traffic |
Memcached | Excellent | Horizontal | No | No | Memcached server | High performance caching |
Database | Good | Vertical | Yes | Yes | None | Audit requirements |
Hybrid | Excellent | Horizontal | Yes | Yes | Redis/Memcached + DB | Production with audit |
*Redis persistence depends on configuration
Memory Sessions¶
Perfect for development and testing environments with no external dependencies.
Basic Usage¶
from crudadmin import CRUDAdmin
# Memory sessions are the default
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key"
)
# Or explicitly configure
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key",
session_backend="memory"
)
Characteristics¶
- Fast: No network overhead
- Simple: No setup required
- Ephemeral: Sessions lost on restart
- Single node: Not suitable for load-balanced deployments
When to Use¶
✅ Development environments
✅ Testing and CI/CD
✅ Single-node applications
❌ Production with multiple instances
❌ Applications requiring session persistence
Redis Sessions¶
Redis provides high-performance session storage with persistence, clustering support, and advanced features like TTL (Time To Live) and Redis ACL authentication.
Installation¶
Basic Configuration¶
from crudadmin import CRUDAdmin, RedisConfig
# Method 1: Using configuration object (recommended)
redis_config = RedisConfig(host="localhost", port=6379, db=0)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key",
session_backend="redis",
redis_config=redis_config
)
# Method 2: URL-based configuration
redis_config = RedisConfig(url="redis://localhost:6379/0")
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key",
session_backend="redis",
redis_config=redis_config
)
# Method 3: Dictionary configuration
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key",
session_backend="redis",
redis_config={"host": "localhost", "port": 6379, "db": 0}
)
Redis with Authentication¶
from crudadmin import CRUDAdmin, RedisConfig
# URL with password
redis_config = RedisConfig(url="redis://user:password@localhost:6379/1")
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key",
session_backend="redis",
redis_config=redis_config
)
# Configuration object with authentication (recommended)
redis_config = RedisConfig(
host="localhost",
port=6379,
db=0,
username="user", # Redis 6.0+ ACL support
password="your-redis-password"
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key",
session_backend="redis",
redis_config=redis_config
)
# Dictionary configuration
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key",
session_backend="redis",
redis_config={
"host": "localhost",
"port": 6379,
"db": 0,
"password": "your-redis-password"
}
)
Production Redis Configuration¶
import os
from crudadmin import CRUDAdmin, RedisConfig
# Environment-based configuration
redis_config = RedisConfig(
host=os.getenv("REDIS_HOST", "localhost"),
port=int(os.getenv("REDIS_PORT", 6379)),
db=int(os.getenv("REDIS_DB", 0)),
password=os.getenv("REDIS_PASSWORD"),
pool_size=20,
connect_timeout=10
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key",
session_backend="redis",
redis_config=redis_config
)
Advanced Redis Parameters¶
from crudadmin import RedisConfig
# Full configuration with all options
redis_config = RedisConfig(
host="redis-cluster.example.com",
port=6379,
db=0,
password="secure-password",
username="redis_user", # Redis 6.0+ ACL support
# Connection pooling
pool_size=20,
connect_timeout=10
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key",
session_backend="redis",
redis_config=redis_config
)
When to Use¶
✅ Production environments
✅ High-traffic applications
✅ Multi-instance deployments
✅ Applications requiring session persistence
✅ Microservices architectures
Configuration Object Examples¶
For comprehensive Redis configuration:
from crudadmin import CRUDAdmin, RedisConfig
# Basic configuration
redis_config = RedisConfig(
host="localhost",
port=6379,
db=0
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key-here",
session_backend="redis",
redis_config=redis_config
)
# With authentication (Redis 6.0+ ACL support)
redis_config = RedisConfig(
host="redis.example.com",
port=6379,
db=1,
username="myapp_user", # Redis ACL username
password="secure_password"
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key-here",
session_backend="redis",
redis_config=redis_config
)
# Advanced Redis configuration with connection pooling
redis_config = RedisConfig(
host="localhost",
port=6379,
db=0,
username="admin_user",
password="secret123",
pool_size=50,
connect_timeout=30
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key-here",
session_backend="redis",
redis_config=redis_config
)
URL-Based Configuration¶
Redis URLs support the standard format including usernames through RedisConfig:
from crudadmin import CRUDAdmin, RedisConfig
# Basic Redis URL
redis_config = RedisConfig(url="redis://localhost:6379/0")
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key-here",
session_backend="redis",
redis_config=redis_config
)
# With password only (legacy authentication)
redis_config = RedisConfig(url="redis://:password123@localhost:6379/0")
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key-here",
session_backend="redis",
redis_config=redis_config
)
# With username and password (Redis 6.0+ ACL)
redis_config = RedisConfig(
url="redis://myuser:password123@redis.example.com:6379/1"
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key-here",
session_backend="redis",
redis_config=redis_config
)
# Complex Redis URL with custom port and database
redis_config = RedisConfig(
url="redis://admin_user:secure_pass@redis-cluster.internal:6380/3"
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key-here",
session_backend="redis",
redis_config=redis_config
)
Authentication Methods¶
Redis supports two authentication methods:
-
Legacy AUTH (Redis < 6.0): Uses only password
from crudadmin import CRUDAdmin, RedisConfig # URL format redis_config = RedisConfig(url="redis://:password@localhost:6379/0") admin = CRUDAdmin( session=get_session, SECRET_KEY="your-secret-key", session_backend="redis", redis_config=redis_config ) # Configuration object format redis_config = RedisConfig(password="password") admin = CRUDAdmin( session=get_session, SECRET_KEY="your-secret-key", session_backend="redis", redis_config=redis_config )
-
ACL Authentication (Redis 6.0+): Uses username and password
from crudadmin import CRUDAdmin, RedisConfig # URL format redis_config = RedisConfig(url="redis://username:password@localhost:6379/0") admin = CRUDAdmin( session=get_session, SECRET_KEY="your-secret-key", session_backend="redis", redis_config=redis_config ) # Configuration object format redis_config = RedisConfig( username="username", password="password" ) admin = CRUDAdmin( session=get_session, SECRET_KEY="your-secret-key", session_backend="redis", redis_config=redis_config )
Memcached Sessions¶
High-performance caching solution optimized for speed over persistence.
Installation¶
# Install Memcached support
uv add "crudadmin[memcached]"
# or with pip
pip install "crudadmin[memcached]"
Basic Configuration¶
from crudadmin import CRUDAdmin, MemcachedConfig
# Method 1: Server list
memcached_config = MemcachedConfig(servers=["localhost:11211"])
admin = CRUDAdmin(
session=get_session,
session_backend="memcached",
memcached_config=memcached_config
)
# Method 2: Individual parameters
memcached_config = MemcachedConfig(host="localhost", port=11211)
admin = CRUDAdmin(
session=get_session,
session_backend="memcached",
memcached_config=memcached_config
)
# Method 3: Dictionary configuration
admin = CRUDAdmin(
session=get_session,
session_backend="memcached",
memcached_config={"host": "localhost", "port": 11211}
)
Multiple Servers¶
from crudadmin import CRUDAdmin, MemcachedConfig
# Multiple servers (first server used due to aiomcache limitations)
memcached_config = MemcachedConfig(servers=[
"memcached1.example.com:11211",
"memcached2.example.com:11211" # Backup server
])
admin = CRUDAdmin(
session=get_session,
session_backend="memcached",
memcached_config=memcached_config
)
Production Memcached Configuration¶
import os
from crudadmin import CRUDAdmin, MemcachedConfig
# Environment-based configuration
memcached_config = MemcachedConfig(
host=os.getenv("MEMCACHED_HOST", "localhost"),
port=int(os.getenv("MEMCACHED_PORT", 11211)),
pool_size=15
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key",
session_backend="memcached",
memcached_config=memcached_config
)
When to Use¶
✅ High-performance requirements
✅ Applications with simple session needs
✅ Existing Memcached infrastructure
❌ Applications requiring session persistence
❌ Audit requirements
Database Sessions¶
Store sessions directly in the database for full admin dashboard visibility and audit trails.
Basic Configuration¶
# Database sessions provide full audit trail
admin = CRUDAdmin(
session=get_session,
session_backend="database"
)
Characteristics¶
- Persistent: Sessions survive application restarts
- Auditable: Full visibility in admin dashboard
- Slower: Database I/O overhead
- Simple: No external dependencies
When to Use¶
✅ Audit requirements
✅ Compliance needs
✅ Small to medium applications
✅ Admin session monitoring
❌ High-traffic applications
❌ Performance-critical scenarios
Hybrid Sessions¶
Combine the performance of Redis/Memcached with the audit capabilities of database storage.
Redis + Database Hybrid¶
from crudadmin import CRUDAdmin, RedisConfig
# Redis for performance + Database for audit trail
redis_config = RedisConfig(
host="localhost",
port=6379,
db=0,
password="redis-password"
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key",
session_backend="redis",
redis_config=redis_config,
track_sessions_in_db=True # Enables hybrid mode
)
Memcached + Database Hybrid¶
from crudadmin import CRUDAdmin, MemcachedConfig
# Memcached for performance + Database for audit trail
memcached_config = MemcachedConfig(
host="localhost",
port=11211
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="your-secret-key",
session_backend="memcached",
memcached_config=memcached_config,
track_sessions_in_db=True # Enables hybrid mode
)
How Hybrid Mode Works¶
- Active sessions stored in Redis/Memcached for fast access
- Session metadata stored in database for admin visibility
- Session operations update both stores
- Admin dashboard shows all sessions from database
- Performance maintained through cache-first approach
When to Use¶
✅ Production environments with audit needs
✅ Compliance requirements + performance
✅ Admin session monitoring + scalability
✅ Best of both worlds scenarios
Environment-Based Configuration¶
Dynamic Configuration¶
import os
from crudadmin import CRUDAdmin, RedisConfig
# Configure backend based on environment
environment = os.getenv("ENVIRONMENT", "development")
if environment == "production":
redis_config = RedisConfig(
host=os.getenv("REDIS_HOST"),
port=int(os.getenv("REDIS_PORT")),
password=os.getenv("REDIS_PASSWORD")
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY=os.environ["ADMIN_SECRET_KEY"],
session_backend="redis",
redis_config=redis_config,
track_sessions_in_db=True
)
elif environment == "staging":
redis_config = RedisConfig(
host=os.getenv("REDIS_HOST", "localhost"),
port=int(os.getenv("REDIS_PORT", 6379))
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY=os.environ["ADMIN_SECRET_KEY"],
session_backend="redis",
redis_config=redis_config,
track_sessions_in_db=True
)
else:
# Development uses memory sessions (default)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY=os.environ["ADMIN_SECRET_KEY"]
)
Configuration Patterns¶
Simple Development Setup¶
from crudadmin import CRUDAdmin
# No external dependencies required
admin = CRUDAdmin(
session=get_session,
SECRET_KEY="dev-key-change-in-production"
)
# Uses memory sessions by default
Production with Redis¶
import os
from crudadmin import CRUDAdmin, RedisConfig
redis_config = RedisConfig(
host=os.environ["REDIS_HOST"],
port=int(os.environ["REDIS_PORT"]),
password=os.environ["REDIS_PASSWORD"]
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY=os.environ["ADMIN_SECRET_KEY"],
session_backend="redis",
redis_config=redis_config,
track_sessions_in_db=True,
secure_cookies=True,
enforce_https=True
)
High Availability Setup¶
import os
from crudadmin import CRUDAdmin, RedisConfig
# Redis cluster with connection pooling
redis_config = RedisConfig(
host=os.environ["REDIS_HOST"],
port=int(os.environ["REDIS_PORT"]),
password=os.environ["REDIS_PASSWORD"],
pool_size=20,
connect_timeout=10
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY=os.environ["ADMIN_SECRET_KEY"],
session_backend="redis",
redis_config=redis_config,
track_sessions_in_db=True
)
Docker Compose Example¶
version: '3.8'
services:
web:
build: .
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=secure-password
- ENVIRONMENT=production
depends_on:
- redis
redis:
image: redis:7-alpine
command: redis-server --requirepass secure-password
volumes:
- redis_data:/data
volumes:
redis_data:
Configuration Validation¶
Built-in Validation¶
CRUDAdmin configuration objects include comprehensive validation:
from crudadmin import RedisConfig, MemcachedConfig
# ✅ URL takes precedence when both URL and individual params are set
redis_config = RedisConfig(
url="redis://localhost:6379/0",
host="ignored", # URL takes precedence
port=9999 # URL takes precedence
)
# ✅ Server list takes precedence for Memcached
memcached_config = MemcachedConfig(
servers=["server1:11211"],
host="ignored", # servers take precedence
port=9999 # servers take precedence
)
# ❌ This will raise ValidationError (invalid port)
try:
redis_config = RedisConfig(port=70000) # Invalid port range
except ValueError as e:
print(f"Validation error: {e}")
# ❌ This will raise ValidationError (negative timeout)
try:
redis_config = RedisConfig(connect_timeout=-5) # Negative timeout
except ValueError as e:
print(f"Validation error: {e}")
Error Handling¶
from crudadmin import CRUDAdmin, RedisConfig
try:
redis_config = RedisConfig(
host="unreachable-redis.example.com",
port=6379
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY=SECRET_KEY,
session_backend="redis",
redis_config=redis_config
)
except ImportError:
# Redis dependencies not installed
print("Redis support not available, falling back to memory")
admin = CRUDAdmin(
session=get_session,
SECRET_KEY=SECRET_KEY,
session_backend="memory"
)
except ConnectionError:
# Redis server unavailable
print("Redis unavailable, using database sessions")
admin = CRUDAdmin(
session=get_session,
SECRET_KEY=SECRET_KEY,
session_backend="database"
)
Performance Considerations¶
Session Cleanup¶
from crudadmin import CRUDAdmin
# Configure automatic cleanup
admin = CRUDAdmin(
session=get_session,
SECRET_KEY=secret_key,
cleanup_interval_minutes=15, # Clean expired sessions every 15 minutes
session_timeout_minutes=30 # Sessions expire after 30 minutes
)
Connection Pooling¶
from crudadmin import CRUDAdmin, RedisConfig
# Redis with optimized connection pooling
redis_config = RedisConfig(
host="redis.example.com",
port=6379,
pool_size=20, # Increase for high traffic
connect_timeout=10
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY=SECRET_KEY,
session_backend="redis",
redis_config=redis_config
)
Session Limits¶
from crudadmin import CRUDAdmin
# Prevent memory exhaustion
admin = CRUDAdmin(
session=get_session,
SECRET_KEY=secret_key,
max_sessions_per_user=10, # Limit concurrent sessions
session_timeout_minutes=30, # Auto-expire sessions
cleanup_interval_minutes=15 # Regular cleanup
)
Monitoring and Debugging¶
Session Metrics¶
# Monitor active sessions
user_sessions = await admin.session_manager.get_user_sessions(user_id)
print(f"User has {len(user_sessions)} active sessions")
# Check session activity
session_data = await admin.session_manager.validate_session(session_id)
if session_data:
session_age = datetime.now(UTC) - session_data.last_activity
print(f"Session last active {session_age} ago")
Debug Logging¶
import logging
# Enable session debug logging
logging.getLogger('crudadmin.session').setLevel(logging.DEBUG)
# Monitor Redis connections
logging.getLogger('redis').setLevel(logging.INFO)
Health Checks¶
# Check backend connectivity
try:
await admin.session_manager.session_storage.exists("health-check")
print("Session backend healthy")
except Exception as e:
print(f"Session backend error: {e}")
Production Deployment Guide¶
Environment Variables¶
Set up these environment variables for production:
# Required
ADMIN_SECRET_KEY=your-secret-key-here
REDIS_HOST=redis.example.com
REDIS_PORT=6379
REDIS_PASSWORD=secure-redis-password
# Optional
REDIS_DB=0
REDIS_POOL_SIZE=20
REDIS_CONNECT_TIMEOUT=10
ENVIRONMENT=production
Then use them in your configuration:
import os
from crudadmin import CRUDAdmin, RedisConfig
# Create configuration from environment variables
redis_config = RedisConfig(
host=os.environ["REDIS_HOST"],
port=int(os.environ["REDIS_PORT"]),
password=os.environ["REDIS_PASSWORD"],
db=int(os.getenv("REDIS_DB", "0")),
pool_size=int(os.getenv("REDIS_POOL_SIZE", "10")),
connect_timeout=int(os.getenv("REDIS_CONNECT_TIMEOUT", "10"))
)
admin = CRUDAdmin(
session=get_session,
SECRET_KEY=os.environ["ADMIN_SECRET_KEY"],
session_backend="redis",
redis_config=redis_config,
# Session management settings from environment
max_sessions_per_user=int(os.getenv("MAX_SESSIONS_PER_USER", "5")),
session_timeout_minutes=int(os.getenv("SESSION_TIMEOUT_MINUTES", "30")),
cleanup_interval_minutes=int(os.getenv("CLEANUP_INTERVAL_MINUTES", "15"))
)
Security Checklist¶
- [ ] Use strong, unique secret keys
- [ ] Configure Redis/Memcached authentication
- [ ] Use TLS/SSL for Redis connections in production
- [ ] Set appropriate session timeouts
- [ ] Enable session cleanup
- [ ] Monitor session backend health
- [ ] Set up session audit logging
Scaling Considerations¶
- Redis Cluster: For high availability and horizontal scaling
- Connection Pooling: Optimize pool sizes for your traffic
- Session Limits: Prevent resource exhaustion
- Monitoring: Track session metrics and backend performance
- Backup Strategy: Plan for session backend failures
Next Steps¶
After configuring your session backend:
- Set up Admin Users for authentication
- Add Models to create your admin interface
- Learn the Interface for daily operations
- Explore Common Patterns for advanced scenarios
For production deployments, see Advanced Topics for comprehensive security, monitoring, and scaling strategies.