DevOps

Gunicorn Worker Calculator

Size Gunicorn workers and threads from CPU count and workload type, choose between sync, gthread and async worker classes, and set the timeouts that stop a slow request taking the process down.

Last reviewed by the Radiatus Cloud team

Worker configuration appears here.

Want this automated for your stack?

We build CI/CD, Kubernetes & IaC pipelines that scale.

Talk to an engineer

The worker class decides everything else

Gunicorn's default sync worker handles exactly one request at a time and blocks for its whole duration, including every millisecond spent waiting on a database or an external API. For an application that spends most of its time waiting, which is most web applications, that wastes almost all of the process. The gthread worker adds threads within each worker so waiting requests do not block others, and gevent or eventlet replace blocking I/O with cooperative scheduling entirely. Picking the wrong class produces a configuration where adding workers does nothing.

The formula and where it stops applying

The documented starting point is two times the core count plus one, which assumes a CPU bound workload where a worker is genuinely computing. For an I/O bound application the limit is memory and concurrency rather than cores, and the useful configuration is fewer processes each with many threads. A Django application spending eighty percent of its time waiting on the database gets far more from four workers with sixteen threads than from seventeen sync workers, and uses a quarter of the memory.

Timeout kills the worker, not the request

Gunicorn's timeout is a watchdog: if a worker does not check in within that window the arbiter kills and replaces it, dropping whatever it was doing. It is not a request timeout in the usual sense, and setting it high to accommodate a slow endpoint means a genuinely hung worker sits there for that long. The better pattern is a short Gunicorn timeout, a separate application level timeout on slow operations, and long running work moved out to a task queue.

Related tools

Frequently Asked Questions

Which worker class should I use?

sync for a CPU bound application with fast responses. gthread for a typical I/O bound web application, which is most of them. gevent or eventlet for very high concurrency with long waits, provided every library in the stack is compatible with monkey patching. uvicorn.workers.UvicornWorker for an ASGI application.

Is workers = 2 × cores + 1 always right?

It is a starting point for CPU bound work. For an I/O bound application the constraint is memory and concurrency rather than cores, and fewer workers with more threads each serves more traffic for less memory.

What does the timeout actually do?

It is a watchdog on the worker rather than a request timeout. If a worker does not signal the arbiter within the window it is killed and replaced, dropping its in-flight request. Raising it to cover a slow endpoint also means a genuinely hung worker persists that long.

Do I still need Nginx in front?

Yes for anything public. Gunicorn is explicitly designed to sit behind a buffering reverse proxy, and without one a slow client can occupy a worker for the whole duration of its upload or download, which is a trivial denial of service.

How do I handle slow requests?

Move them out of the request path into a task queue such as Celery or RQ and return immediately. Raising timeouts to accommodate slow work means every worker can be occupied by it, and the timeout no longer protects against a hang.

Privacy & Security

Everything runs in your browser; nothing is uploaded.

Data: None
Client-side-Side
Active
v1.0

How to Use

Enter your core count and request profile to get a worker configuration and command line.

Disclaimer: This tool is provided "as is" without warranty of any kind. Results are for educational and utility purposes.