Django Channels and WebSockets Production Checklist
A production checklist for Django Channels: ASGI server choice, Redis channel layer, WebSocket proxy configuration, authentication and origin checks, consumer performance, scaling, timeouts and heartbeats, deploys, and monitoring.
Problem statement
Django Channels adds WebSockets and long-lived connections to Django, and with them a different set of production concerns: an ASGI server instead of (or beside) Gunicorn, a channel layer shared across processes, proxies that must upgrade connections and not time them out, authentication and origin checks for a protocol that bypasses CSRF, and clients that reconnect gracefully. This checklist covers what to verify before real users rely on live features.
- Serve ASGI with Daphne or Uvicorn (often under Gunicorn), supervised and behind Nginx or a load balancer.
- Use
channels_redison a dedicated Redis instance; never the in-memory layer. - Configure the proxy for WebSocket upgrades and long idle timeouts; send heartbeats.
- Wrap the router in
AllowedHostsOriginValidatorandAuthMiddlewareStack; authorise per consumer. - Keep consumers fast; move database writes and external calls to async code or Celery.
- Make clients reconnect with backoff and resync state after deploys.
Checklist
Server and routing
asgi.pyusesProtocolTypeRouterwith HTTP to Django and WebSocket routes to consumers.- ASGI processes are supervised (systemd, containers) with graceful shutdown.
- WebSocket paths (for example
/ws/) route to ASGI processes; HTTP can stay on WSGI if preferred.
Channel layer
CHANNEL_LAYERSpoints at Redis (RedisChannelLayerorRedisPubSubChannelLayer).- Redis instance separate from cache and Celery broker, with memory limits and monitoring.
- Capacity and expiry settings reviewed for message bursts.
Proxy and timeouts
- Nginx location sets
proxy_http_version 1.1,Upgrade, andConnectionheaders. proxy_read_timeout(and load balancer idle timeout) well above the heartbeat interval.- Application-level heartbeats every 20-30 seconds for idle connections.
- TLS terminates at the proxy; clients use
wss://.
Security
AllowedHostsOriginValidatorrejects WebSocket handshakes from other origins (WebSockets are not covered by CSRF).AuthMiddlewareStack(or token auth middleware) populatesscope["user"]; consumers check permissions for every group they join.- Message size limits and per-connection rate limits for user-sent messages.
Consumers and performance
- Async consumers use
database_sync_to_asyncor the async ORM; no blocking calls. - Heavy work (persistence, notifications, external APIs) is queued to Celery.
- Group sizes and broadcast frequency are bounded; large fan-outs are throttled.
Deploys and monitoring
- Rolling restarts; clients reconnect with exponential backoff and resync missed data.
- Metrics: active connections per process, messages per second, Redis memory and CPU, consumer errors.
- Load-tested with the expected number of concurrent connections.
Explanation
WebSockets turn a request-response app into one with thousands of long-lived connections, each held by an ASGI process. Messages between users connected to different processes travel through the channel layer, so it must be shared and sized for fan-out. Proxies must explicitly support the protocol upgrade and tolerate idle periods. Because browsers send cookies with WebSocket handshakes from any origin and CSRF does not apply, origin validation and per-group authorisation are the security controls. Finally, connections inevitably drop, so clients must recover on their own.
Edge cases / notes
- Mixed WSGI and ASGI: many teams keep HTTP on Gunicorn sync workers and route only
/ws/to ASGI. - Server-sent events are simpler than WebSockets for server-to-client updates and work with standard HTTP infrastructure.
- Managed realtime services (Pusher, Ably) remove connection handling from your servers for very large audiences.
- Mobile clients suspend sockets in the background; design for reconnection.
Next steps
- Set it up with Deploy Django Channels With Daphne and WebSockets.
- Grow it with Scale Django Channels WebSockets Across Servers.
FAQ
What do I need to run Django Channels in production?
An ASGI server, a Redis channel layer, a WebSocket-capable proxy, origin and auth checks, and reconnecting clients.
Can I use the in-memory channel layer in production?
No. It only works within a single process.
Are WebSockets protected by Django's CSRF?
No. Use AllowedHostsOriginValidator and authorise users in consumers.
Why do WebSockets disconnect after a minute?
Proxy or load balancer idle timeouts. Raise them and send heartbeats.