I am running some siege tests on my nginx server. The bottleneck doesn't seem to be cpu or memory so what is it?

I try to do this on my macbook:

sudo siege -t 10s -c 500 server_ip/test.php

The response time goes to 10 seconds, I get errors and siege aborts before completing.

But I if run the above on my server

siege -t 10s -c 500 localhost/test.php

I get:

Transactions:               6555 hits
Availability:              95.14 %
Elapsed time:               9.51 secs
Data transferred:         117.30 MB
Response time:              0.18 secs
Transaction rate:         689.27 trans/sec
Throughput:            12.33 MB/sec
Concurrency:              127.11
Successful transactions:        6555
Failed transactions:             335
Longest transaction:            1.31
Shortest transaction:           0.00

I also noticed for lower concurrent figures, I get vastly improved transaction rate on localhost compared to externally.

But when the above is running on localhost the CPU usage is low, memory usage is low on HTOP. So I'm confused how I can boost performance because I can't see a bottleneck.

ulimit returns 50000 because I've increased it. There are 4 nginx worker processes which is 2 times my cpu cores. Here are my other settings

worker_rlimit_nofile 40000;

events {
        worker_connections 20000;
        # multi_accept on;

  tcp_nopush on;
  tcp_nodelay on;
  keepalive_timeout 65;
  types_hash_max_size 2048;

The test.php is just a echo phpinfo() script, nothing else. No database connections.

The machine is an AWS m3 large, 2 cpu cores and about 7gb of ram I believe.

Here is the contents of my server block:

      listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;

        root /var/www/sitename;
        index index.php index.html index.htm;

        # Make site accessible from http://localhost/
        server_name localhost;

        location / {
                try_files $uri $uri.html $uri/ @extensionless-php;

location @extensionless-php {
    rewrite ^(.*)$ $1.php last;

        error_page 404 /404.html;

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
                root /usr/share/nginx/html;

        # pass the PHP scripts to FastCGI server listening on
        location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;

My php-fpm settings:

 pm = dynamic

; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
; This value sets the limit on the number of simultaneous requests that will be
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
; CGI. The below defaults are based on a server without much resources. Don't
; forget to tweak pm.* to fit your needs.
; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
; Note: This value is mandatory.
pm.max_children = 40

; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
pm.start_servers = 30

; The desired minimum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.min_spare_servers = 20

; The desired maximum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.max_spare_servers = 35

; The number of seconds after which an idle process will be killed.
; Note: Used only when pm is set to 'ondemand'
; Default Value: 10s
;pm.process_idle_timeout = 10s;

; The number of requests each child process should execute before respawning.
; This can be useful to work around memory leaks in 3rd party libraries. For
; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.
; Default Value: 0
;pm.max_requests = 500
  • Could you post your PHP-FPM settings? Sounds like your php process pool is starving due to high connection concurrency.
    – ma.tome
    Aug 3, 2015 at 22:24
  • What is "server_ip"? On a private network? Is there any reverse DNS lookup being done? Aug 4, 2015 at 21:35
  • @ma.tome I have posted them. Interested in your input Aug 4, 2015 at 21:35
  • @Kkinsey That's something I put in in the answer in place of the actual server ip. Aug 4, 2015 at 21:36
  • 1
    What are the exact error messages that you get from the mac ?
    – user9517
    Aug 4, 2015 at 21:43

1 Answer 1


500 concurrent requests are way too much for such a little PHP process pool. Try raising your min and max php processes and test again until you reach the maximum CPU usage.

Most surely, if you perform your tests with lower client concurrency (maybe 100 due to your low CPU usage per request) you will get a better global performance and no request errors. The same way, if you perform your test for longer periods of time you should observe worse and worse statistics and higher error ratios.

Anyway, once you reach your 100% CPU usage test scenario, keep in mind thatwhen you deploy your production code these pool values won't be of any use. A typical PHP e-commerce application is CPU intensive enough to starve your 2 vCPUs with barely 4-5 concurrent checkouts.

Typically, CPU or memory intensive applications will better work with small PHP process pools, while fast low CPU applications will make better use of large pools.

  • 1
    Thanks. Can you be more specific when you say raise my min and max processes? Which of these should I increase: max_children, start_servers, min_spare_servers, min_spare_servers, max_requests? Aug 5, 2015 at 10:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.