[Fixed]-Gunicorn sync workers spawning processes


In my case I deploy in Ubuntu servers (LTS releases, now almost are 14.04 LTS servers) and I never did have problems with gunicorn daemons, I create a gunicorn.conf.py and launch gunicorn with this config from upstart with an script like this in /etc/init/djangoapp.conf

description "djangoapp website"
start on startup
stop on shutdown
respawn limit 10 5

  cd /home/web/djangoapp
  exec /home/web/djangoapp/bin/gunicorn -c gunicorn.conf.py -u web -g web djangoapp.wsgi
end script

I configure gunicorn with a .py file config and i setup some options (details below) and deploy my app (with virtualenv) in /home/web/djangoapp and no problems with zombie and orphans gunicorn processes.

i verified your options, timeout can be a problem but another one is that you don’t setup max-requests in your config, by default is 0, so, no automatic worker restart in your daemon and can generate memory leaks (http://gunicorn-docs.readthedocs.org/en/latest/settings.html#max-requests)


We will use a .sh file to start the gunicorn process. Later you will use a supervisord configuration file. what is supervisord? some external know how information link about how to install supervisord with Django,Nginx,Gunicorn Here

gunicorn_start.sh remember to give chmod +x to the file.

echo "Starting myDjango -- Django Application"
exec gunicorn -w $NUM_WORKERS $NAME.wsgi:application --bind

mydjango_django.conf : Remember to install supervisord on your OS. and
Copy this on the configuration folder.


Later on use the command:

Reload the daemon’s configuration files, without add/remove (no restarts)

supervisordctl reread

Restart all processes Note: restart does not reread config files. For that, see reread and update.

supervisordctl start all

Get all process status info.

supervisordctl status 


This sounds like a timeout issue.

You have multiple timeouts going on and they all need to be in a descending order. It seems they may not be.

For example:

  • Nginx has a default timeout of 60 seconds
  • Gunicorn has a default timeout of 30 seconds
  • Django has a default timeout of 300 seconds
  • Postgres default timeout is complicated but let’s pose 60 seconds for this example.

In this example, when 30 seconds has passed and Django is still waiting for Postgres to respond. Gunicorn tells Django to stop, which in turn should tell Postgres to stop. Gunicorn will wait a certain amount of time for this to happen before it kills django, leaving the postgres process as an orphan query. The user will re-initiate their query and this time the query will take longer because the old one is still running.

I see that you have set your Gunicorn tiemeout to 300 seconds.

This would probably mean that Nginx tells Gunicorn to stop after 60 seconds, Gunicorn may wait for Django who waits for Postgres or any other underlying processes, and when Nginx gets tired of waiting, it kills Gunicorn, leaving Django hanging.

This is still just a theory, but it is a very common problem and hopefully leads you and any others experiencing similar problems, to the right place.

Leave a comment