Deployment
Choosing Your Server
| Use Case | Recommended Server | Why |
|---|---|---|
Sync views only (def) |
Gunicorn (WSGI) | Mature, stable, simple |
Async views (async def) |
Uvicorn, Daphne (ASGI) | Native async support, better concurrency |
| Mixed sync/async | Uvicorn (ASGI) | Handles both seamlessly |
Not sure?
Start with Uvicorn — it supports both sync and async views, and is the recommended default for django-flosse v0.2.0+.
ASGI — Uvicorn (Recommended for Async)
For best performance with async def SSE views, run your project with an ASGI server:
Why these flags?
--workers: Scale horizontally (one per CPU core)--loop uvloop: Faster event loop (optional but recommended)--http h11: Better SSE compatibility with some proxies
Production Example (with Gunicorn + Uvicorn workers)
gunicorn myproject.asgi:application \
-k uvicorn.workers.UvicornWorker \
--workers 4 \
--worker-connections 1000 \
--timeout 120
WSGI — Gunicorn (Sync Only)
Each SSE connection holds one WSGI worker for its entire duration.
Use gthread workers so each worker can serve multiple streams concurrently:
This allows up to workers × threads = 8 concurrent SSE streams per server.
Tuning
Start with --workers $(nproc) and --threads 4.
Increase --threads if most connections are idle (SSE is I/O-bound).
Async views on WSGI
Async generators will run in a thread pool on WSGI servers, negating most performance benefits. Use ASGI for async def views.
WSGI — uWSGI
Nginx
X-Accel-Buffering: no is set automatically by @sse_stream — no extra
Nginx config is required for buffering.
For long-lived connections, increase the read timeout:
location /sse/ {
proxy_pass http://django;
proxy_read_timeout 3600;
proxy_buffering off;
proxy_cache off;
}
Cloudflare / CDN users
Add these headers to prevent proxy buffering:
Compatibility
| django-flosse | Django | Python | Server Support |
|---|---|---|---|
| 0.1.x | 3.2 – 6.0 | 3.9 – 3.14 | WSGI only |
| 0.2.0+ | 4.2 – 6.0 | 3.9 – 3.14 | WSGI + ASGI |
Async support is here!
Native async def generator views are available in v0.2.0+.
Use an ASGI server (Uvicorn, Daphne) for best performance.
See Async Support Guide for details.
Monitoring & Health Checks
Log Stream Lifecycle
# settings.py
LOGGING = {
"version": 1,
"handlers": {
"console": {"class": "logging.StreamHandler"},
},
"loggers": {
"django_flosse": {
"handlers": ["console"],
"level": "INFO",
},
},
}
Simple Health Endpoint
# views.py
from django.http import JsonResponse
def sse_health(request):
return JsonResponse({
"status": "ok",
"sse_support": True,
"async_ready": True, # v0.2.0+
})
Troubleshooting
| Issue | Solution |
|---|---|
| Connections drop after ~60s | Disable proxy buffering; increase proxy_read_timeout |
| Async views run slowly | Ensure you're using ASGI (Uvicorn), not WSGI |
| High memory usage per worker | Reduce --threads (WSGI) or --workers (ASGI); monitor with psutil |
CancelledError in logs |
Normal on disconnect; handle gracefully or suppress |
| SSE not working behind Cloudflare | Add proxy_set_header Connection '' + disable caching |