Courses Quizzes Articles Contact
Login
Deploying Python backend to AWS Step 2 of 14 · Easy · One process on one instance
TECH

Gunicorn instead of runserver

Karen Created Oct 13, 2026 Updated Oct 13, 2026 1 min read

Gunicorn is a WSGI server. It loads your Django project and answers HTTP with several worker processes. runserver is a single process that Django ships for development. It reloads code, it is not built for concurrent users, and it should not be the process on a public port.

gunicorn project.wsgi:application --bind 0.0.0.0:8000 --workers 3

project.wsgi:application is the callable Django generated. --bind 0.0.0.0:8000 listens on every interface of the machine, on port 8000. Inside Docker that is the container’s port. On an instance, the security group should not open 8000 to the world. The next lesson puts Nginx on port 80 and leaves 8000 for Nginx alone.

Workers are processes, not threads you guess

Three workers means three processes that can each handle a request. A worker blocked on the database does not block the others. More workers than CPU cores mostly wait. Start with two or three on a t3.micro and raise the number only when requests are waiting and the CPU is idle.

Gunicorn does not serve your CSS and JavaScript well. Django’s collectstatic gathers those files into STATIC_ROOT. Something else has to hand them to the browser. That something is Nginx.

You're reading a free lesson from Deploying Python backend to AWS

The rest of the lessons are not for sale yet.