Production Deployment: Nginx, Timeouts & Graceful Restarts
Nginx in Front of Gunicorn
A very common stack: Nginx sits in front of Gunicorn as a reverse proxy, handling TLS termination, static file serving, and buffering slow client connections. Buffering matters specifically because a sync worker is occupied for a request's full duration — an unbuffered slow client connected directly to Gunicorn could tie up a worker for the whole slow transfer, reducing capacity for everyone else.
Timeouts & Worker Recycling
gunicorn --timeout 30 --max-requests 1000 --max-requests-jitter 50 myapp:app--timeout kills and restarts a worker that doesn't respond within the given time, guarding against hung requests. --max-requests restarts a worker after handling that many requests, a pragmatic mitigation for gradual memory leaks in application/dependency code without needing to hunt down the leak immediately.
Deploys & Graceful Restarts
Each worker loads application code once at startup, so deploying new code requires restarting workers to pick it up. Sending SIGHUP to the master process triggers a graceful restart — replacing workers while letting in-flight requests on the old ones finish, minimizing dropped connections during a deploy.
ASGI Apps & Alternatives
Gunicorn speaks WSGI natively; an ASGI framework like FastAPI typically runs via `gunicorn -k uvicorn.workers.UvicornWorker`, using Gunicorn as a process manager fronting Uvicorn workers rather than Gunicorn handling ASGI directly. uWSGI is the most commonly cited alternative WSGI server — more feature-rich and configurable, but generally considered more complex to configure well than Gunicorn's simpler defaults.
Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free