title: Nginx + PHP-FPM Using CPU and Not RAM
body: <p>I am doing load testing on an Nginx Server and I am having an issue where my CPU hits 100% but only 50% of my ram is being utilized. The server is this:</p>
  
  <pre><code>2 vCPU
  2 GB of RAM
  40GB SSD Drive
  Rackspace High Performance Server
  </code></pre>
  
  <p>This is my Nginx Config</p>
  
  <pre><code>worker_processes  2;
  error_log  /var/log/nginx/error.log crit;
  
  pid        /var/run/nginx.pid;
  
  events {
      worker_connections  1524;
      use epoll;
      multi_accept on;
  }
  
  http {
      include   /etc/nginx/mime.types;
      default_type  application/octet-stream;
  
      log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for"';
  
      #access_log  /var/log/nginx/access.log  main;
      access_log off;
  
      # Sendfile copies data between one FD and other from within the kernel.
      # More efficient than read() + write(), since the requires transferring data to and from the user space.
      sendfile on;
  
      # Tcp_nopush causes nginx to attempt to send its HTTP response head in one packet,
      # instead of using partial frames. This is useful for prepending headers before calling sendfile,
      # or for throughput optimization.
      tcp_nopush on;
  
      # don't buffer data-sends (disable Nagle algorithm). Good for sending frequent small bursts of data in real time.
      tcp_nodelay on;
  
      # allow the server to close the connection after a client stops responding. Frees up socket-associated memory.
      reset_timedout_connection on;
  
      #keepalive_timeout  0;
      keepalive_timeout  65;
  
      # send the client a "request timed out" if the body is not loaded by this time. Default 60.
      client_body_timeout 10;
  
      # If the client stops reading data, free up the stale client connection after this much time. Default 60.
      send_timeout 2;
  
      open_file_cache max=200000 inactive=20s;
      open_file_cache_valid 30s;
      open_file_cache_min_uses 2;
      open_file_cache_errors on;
  
      gzip  on;
      server_tokens off;
  
      client_max_body_size 20m;
      client_body_buffer_size 128k;
  
  client_max_body_size 20m;
      client_body_buffer_size 128k;
  
      gzip_min_length 10240;
      gzip_proxied expired no-cache no-store private auth;
      gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
      gzip_disable "MSIE [1-6]\.";
  
      # Load config files from the /etc/nginx/conf.d directory
      # The default server is in conf.d/default.conf
  
      fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=microcache:10m max_size=1000m inactive=60m;
  
      include /etc/nginx/conf.d/*.conf;
      include /etc/nginx/sites-enabled/*;
  
  }
  </code></pre>
  
  <p>Kernal additions in /etc/sysctl.conf </p>
  
  <pre><code># Increase system IP port limits to allow for more connections
  
  net.ipv4.ip_local_port_range = 2000 65000
  
  
  net.ipv4.tcp_window_scaling = 1
  
  
  # number of packets to keep in backlog before the kernel starts dropping them
  net.ipv4.tcp_max_syn_backlog = 3240000
  
  
  # increase socket listen backlog
  net.core.somaxconn = 3240000
  net.ipv4.tcp_max_tw_buckets = 1440000
  
  
  # Increase TCP buffer sizes
  net.core.rmem_default = 8388608
  net.core.rmem_max = 16777216
  net.core.wmem_max = 16777216
  net.ipv4.tcp_rmem = 4096 87380 16777216
  net.ipv4.tcp_wmem = 4096 65536 16777216
  net.ipv4.tcp_congestion_control = cubic
  </code></pre>
  
  <p>Example VHost Config with PHP-FPM</p>
  
  <pre><code>server {
      listen   80;
  
      server_name  www.example.com;
  
      location / {
          root   /data/sites/example.com/public_html;
          index  index.php index.html index.htm;
  
          try_files $uri $uri/ /index.php?rt=$uri&amp;$args;
      }
  
     location ~ \.php {
        root          /data/sites/example.com/public_html;
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param  SCRIPT_NAME $fastcgi_script_name;
        fastcgi_index  index.php;
        fastcgi_param PATH_INFO $fastcgi_script_name;
        fastcgi_param ENV production;
        include        fastcgi_params;
      }
  }
  </code></pre>
  
  <p>The server can handle about 60 active SBU connections clicking around, or about 300 request per second. Is the fact that is not fully utilizing RAM and more CPU a bad thing? Can I optimize this further?</p>