I'm developing a Flask web application that uses SocketIO and am facing issues with configuring Gunicorn, particularly with the number of workers and threads. My server runs on Ubuntu with 32GB DDR4 memory and an i7 7700k CPU. I've tried several configurations, but I'm puzzled by the performance results and SocketIO errors I'm encountering. Here's what happens with different commands:
gunicorn --bind 0.0.0.0:5000 wsgi:app
Result: Extremely poor performance and SocketIO errors.
gunicorn -w 12 -t 3 --bind 0.0.0.0:5000 wsgi:app
Result: Great performance but still SocketIO errors.
gunicorn -k eventlet -w 1 -t 100 --bind 0.0.0.0:5000 wsgi:app
Result: Great performance and no SocketIO errors.
gunicorn -k eventlet -w 2 -t 100 --bind 0.0.0.0:5000 wsgi:app
Result: Great performance but back to SocketIO errors.
Given the above scenarios, I have several questions:
eventlet -w 1
is allocating single worker for eventlet, then is my program being allocated extra workers automatically? If not then why is my app performing good?eventlet
is good for IO bound
tasks. So, you 'll get a good performance with this type worker. Thread option -t 100
mean the server will handle 100 request in the same time, when many requests come worker master load 100 request to child worker that deployed application. Because requests are mostly IO tasks, they are processed "concurrently" by eventlet mode. If you set a few --thread
, the server is low performance
-w 1
option. So, if you use Flask-SocketIO version < 2.0
, It doesn't support multiple workers and leads to errors. Each worker has a different memory area that leading client's request being divided among another worker that was not processed by the previous workerFlask-SocketIO >= 2.0
and need a queue
such as redis for many workers can get client connections of the other worker before increase number worker.