Gunicorn 26.0.0
Overview
Gunicorn (Green Unicorn) is a Python WSGI HTTP server for UNIX, using a pre-fork worker model ported from Ruby's Unicorn. It is broadly compatible with web frameworks, simply implemented, light on resources, and production-proven since 2010.
Version 26.0.0 builds on v25 features including Dirty Arbiters (separate process pools for heavy workloads), HTTP/2 support, the native ASGI worker, and the gunicornc control interface. Requires Python 3.12+.
When to Use
- Deploying a Python web application (Django, Flask, FastAPI, Starlette) to production
- Tuning Gunicorn worker counts, timeouts, or thread pools
- Configuring reverse proxy integration (Nginx, HAProxy) with Gunicorn
- Setting up ASGI workloads with WebSockets, streaming, or Dirty Arbiters
- Managing Gunicorn at runtime via signals or the
gunicornccontrol interface - Choosing between worker types (sync, gthread, gevent, ASGI) for a specific workload
Core Concepts
Pre-fork Worker Model
Gunicorn runs an arbiter (master) process that manages a pool of worker processes. The arbiter listens on sockets and distributes connections to workers. Workers handle requests independently — a worker crash affects only its in-flight requests.
Configuration Priority Chain
Gunicorn reads configuration from five sources, increasing priority:
- Environment variables (per-setting support)
- Framework-specific config (Paste Deploy)
- Python config file (
gunicorn.conf.py, auto-loaded from working directory) GUNICORN_CMD_ARGSenvironment variable- Command-line arguments (highest priority)
Print fully resolved config: gunicorn --print-config APP_MODULE
Validate and exit: gunicorn --check-config APP_MODULE
Worker Types
| Worker | Concurrency | Keep-Alive | Best For |
|---|---|---|---|
sync (default) |
1 request/worker | No | CPU-bound apps behind a buffering proxy |
gthread |
Thread pool | Yes | Mixed workloads, moderate concurrency |
gevent |
Greenlets | Yes | I/O-bound, WebSockets, streaming |
asgi |
AsyncIO | Yes | FastAPI, Starlette, Quart (async frameworks) |
tornado |
Tornado IOLoop | Yes | Native Tornado applications |
Installation / Setup
# Quick install
pip install gunicorn
# With async extras
pip install gunicorn[gevent,setproctitle]
# In a virtual environment (recommended)
python -m venv venv && source venv/bin/activate
pip install gunicorn
# Docker
docker pull ghcr.io/benoitc/gunicorn:latest
Usage Examples
Basic WSGI (Flask)
gunicorn app:app --workers 4
Django
gunicorn myproject.wsgi --workers 4
FastAPI (ASGI)
gunicorn main:app --worker-class asgi --workers 4
With a Configuration File
Create gunicorn.conf.py:
import multiprocessing
bind = "0.0.0.0:8000"
workers = multiprocessing.cpu_count() * 2 + 1
accesslog = "-"
errorlog = "-"
loglevel = "info"
Run (auto-loads gunicorn.conf.py from current directory):
gunicorn app:app
Worker Count Formula
Start with 2 * CPU_CORES + 1 workers, adjust under load. Use TTIN/TTOU signals to scale at runtime.
Advanced Topics
Configuration Settings: Full reference of all Gunicorn settings with defaults and descriptions → Configuration Settings
Deployment Patterns: Nginx proxy, systemd socket activation, Docker, PROXY protocol, process managers → Deployment Patterns
Workers and Customization: Worker type selection, ASGI worker details, Dirty Arbiters for heavy workloads, custom applications → Workers and Customization
Operations: Signal handling, binary upgrades, logging, statsD instrumentation, FAQ → Operations