title: uWSGI python highload configuration
body: <p>We have a big EC2 instance with 32 cores, currently running Nginx, Tornado and Redis, serving on average 5K requests per second. Everything seems to work fine, but the CPU load already reaching 70% and we have to support even more requests. One of the thoughts was to replace Tornado with uWSGI because we don't really use async features of Tornado. </p>
  
  <p>Our application consist from one function, it receives a JSON (~=4KB), doing some blocking but very fast stuff (Redis) and return JSON. </p>
  
  <ul>
  <li>Proxy HTTP request to one of the Tornado instances (Nginx) </li>
  <li>Parse HTTP request (Tornado) </li>
  <li>Read POST body string (stringified JSON) and convert it to python dictionary (Tornado) </li>
  <li>Take data out of Redis (blocking) located on same machine (py-redis with hiredis) </li>
  <li>Process the data (python3.4) </li>
  <li>Update Redis on same machine (py-redis with hiredis) </li>
  <li>Prepare stringified JSON for response (python3.4) </li>
  <li>Send response to proxy (Tornado) </li>
  <li>Send response to client (Nginx)</li>
  </ul>
  
  <p>We thought the speed improvement will come from uwsgi protocol, we can install Nginx on separate server and proxy all requests to uWSGI with uwsgi protocol. But after trying all possible configurations and changing OS parameters we still can't get it working even on current load.
  Most of the time nginx log contains 499 and 502 errors. In some configurations it just stopped receiving new requests like it hit some OS limit.</p>
  
  <p>So as I said, we have 32 cores, 60GB free memory and very fast network. We don't do heavy stuff, only very fast blocking operations. What is the best strategy in this case? Processes, Threads, Async? What OS parameters should be set?</p>
  
  <p>Current configuration is:</p>
  
  <pre><code>[uwsgi]
  master = 2
  processes = 100
  socket = /tmp/uwsgi.sock
  wsgi-file = app.py
  daemonize = /dev/null
  pidfile = /tmp/uwsgi.pid
  listen = 64000
  stats = /tmp/stats.socket
  cpu-affinity = 1
  max-fd = 20000
  memory-report = 1
  gevent = 1000
  thunder-lock = 1
  threads = 100
  post-buffering = 1
  </code></pre>
  
  <p>Nginx config:</p>
  
  <pre><code>user www-data;
  worker_processes 10;
  pid /run/nginx.pid;
  
  events {
      worker_connections 1024;
      multi_accept on;
      use epoll;
  }
  </code></pre>
  
  <p>OS config:</p>
  
  <pre><code>sysctl net.core.somaxconn
  net.core.somaxconn = 64000
  </code></pre>
  
  <p>I know the limits are too high, started to try every value possible.</p>
  
  <p><strong>UPDATE</strong>:</p>
  
  <p>I ended up with the following configuration:</p>
  
  <pre><code>[uwsgi]
  chdir = %d
  master = 1
  processes = %k
  socket = /tmp/%c.sock
  wsgi-file = app.py
  lazy-apps = 1
  touch-chain-reload = %dreload
  virtualenv = %d.env
  daemonize = /dev/null
  pidfile = /tmp/%c.pid
  listen = 40000
  stats = /tmp/stats-%c.socket
  cpu-affinity = 1
  max-fd = 200000
  memory-report = 1
  post-buffering = 1
  threads = 2
  </code></pre>