Increase PHP script execution time with Nginx

If you have a large WordPress setup or a server with limited resources, then you will often see the “504 Gateway Time-out” error.

You can follow the steps given below to increase the timeout value. PHP default is 30s.

Changes in php.ini

If you want to change max execution time limit for php scripts from 30 seconds (default) to 300 seconds.


In Apache, applications running PHP as a module above would have suffice. But in our case we need to make this change at 2 more places.

Changes in PHP-FPM

This is only needed if you have already un-commented request_terminate_timeout parameter before. It is commented by default, and takes value of max_execution_time found in php.ini



Changes in Nginx Config

To increase the time limit for by

If you want to increase time-limit for all-sites on your server, you can edit main nginx.conf file:

Add following in http{..} section

Reload PHP-FPM & Nginx

Don’t forget to do this so that changes you have made will come into effect:

Source :

Optimasi Plugin WP Super Cache di Nginx Web Server

Hello mas brot, lagi2 artikel ini hanyalah kopas mentah2 belaka karena memang ogut sangat tidak pandai bikin artikel, apalagi tutorial xexexexexex….

Bagi yang ga ngerti apa itu web server, nginx, ssh lan konco2ne mending ga usah baca artikel ini, dari pada nanti malah pusing, klemun2, terus mutah :v

Okelah kalo begitu, karena 2 paragraph di atas saya sudah yakin sangat unik sekali karena memang hasil pemikiran sendiri, jadi mari kita masuk ke Kopas 😀

Standard WordPress-Nginx configuration with WP Super cache support:

As you are getting into Nginx, I hope you don’t need my help with configuring WP Super Cache plugin.

Still, make sure you are using “Use mod_rewrite to serve cache files. (Recommended)” option under “Advanced” tab.

Following configuration supports:

  1. Static Page Caching using Disk
  2. Direct browser cache for static content like images, js, css, etc



To simplify configuration, I haven’t added Mobile user agent checks. We are in the iPhone era where finally phones are getting smart. So there is no need to create separate mobile site, when you can cater to today’s iPhone/Android devices using responsive designs.

Don’t Forget:

Always test your Nginx configuration and then reload it. All changes to Nginx config must be followed with these commands:

Important Note:

WP Super Cache caching will conflict with plugins that uses query vars. WooCommerce is an example known plugin known to work with above configuration. Reason is following line: 

It doesn’t passes $args to /index.php. If you set last try_files argument to /index.php?$args as with other WordPress-Nginx configuration, WP Super Cache, itself will break!

if you get error like this “Mod rewrite may not be installed” just install this plugin the remove the error

Artikel ini sepenuhnya diKopas dari –>

Mobile redirect dengan Nginx server

Dicopas sepenuhnya dari  😀

Using Nginx for redirection

Visitors should not have to go to the Rails app just to be redirected away from it. By having the logic in Nginx, we can reduce unnecessary request to the Rails app and also reuse the implementation for other projects that might be built with Node.js, Python, static HTML, or something else.

Defining the flow

The logic that most websites use for desktop / mobile redirection:

  • Mobile devices visiting should redirect to
  • Desktop clients should continue to
  • Mobile devices should be allowed to the desktop website if visiting through
  • A cookie should be set when a mobile device chooses the desktop version to remember the choice.

Redirecting to mobile website

To start, here is a very basic Nginx server configuration that can serve static pages.


The redirection logic is actually quite simple, but one gotcha is that if blocks in Nginx can be unpredictable. There is even an article on the Nginx Wiki about the evils of if.

Because of this, if blocks are kept out of a location context and only used for setting variables, with one exception being the actual redirection.


The $mobile_request variable is initialized as false, then is set to true if the requesting browser is a mobile device. Finally, if the $mobile_request variable is true, a redirect happens.

Setting a cookie, checking a cookie

Cookie creation should be handled in Nginx, too, but I had some initial issues since add_header cannot be inside an if block in the server context (though it can in the location context).

Because of the add_header restriction, the $mobile_cookie variable needs to be initialized before the if block that could set it to false, because add_header Set-Cookie is always going to be used.


Exceptions to the redirection

One major issue that can come up from this implementation is the mobile check happens on every HTTP request through Nginx. This is not a problem for our company website since assets are hosted on Amazon S3, but if your hosting assets at /assets/ or elsewhere, you’ll need to add exceptions to treat all request to that directory or file as non-mobile.


All together

Because of the $request_uri in the redirection block, the code assumes the routes of your desktop website and mobile website will be the same, or at least mapped accordingly on the mobile side of the implementation, but that’s another post.

Nginx + Php-fpm + Varnish Cache + WordPress

10 Million hits per day with WordPress on a $15 virtual server

Install Ubuntu 11.10 (Oneiric) on a new virtual private server- it needs to be 11.10 for all the packages that I’m going to list to work out of the box, but it’s all possible to do with other distributions.

I used Amazon EC2 to build my test server, but Linode are also very good.

For the purpose of the documentation, my server details were as follows, yours will be different:

Public DNS Name:
Public IP Address:

Login to the server and become root

login as ubuntu via ssh, then run the sudo -i command to become root

sudo -i

Configure a firewall first

Since we’re going to be installing various network services which by default listen on all interfaces, it’s important to configure a firewall.

For Ubuntu, this is nice and easy, simply use the ufw package.

Execute the following commands to configure it:

ufw allow ssh
ufw allow http
ufw logging off
ufw enable

Once this is done, your server has a relatively secure firewall, though it’s worth looking at fail2ban to prevent brute force password attacks.

If you’re using Amazon EC2, you’ll also need to open the Security Group to allow traffic on port 80. You can do this using the AWS Security Groups Console, you might need to change the region. Select the security group you used when you started the instance, and then click “Inbound”, then select “HTTP” from the drop down menu, then finally click “Add Rule”. You don’t need to restart the instance for it to take effect.

Install and Configure MySQL

apt-get update
apt-get install mysql-server

When prompted, set a mysql “root” user password

mysql -u root -p

When prompted, enter your newly set root password

At the mysql> prompt, run the following 4 commands, replacing ENTER_A_PASSWORD with a password of your own


That’s MySQL installed, ready for the PHP and Web server installation (nginx).

Install and configure PHP

We need to install not just PHP, but the PHP FPM system, APC, and the MySQL module

apt-get install php5-fpm php-pear php5-common php5-mysql php-apc php5-gd

Edit /etc/php5/fpm/php.ini and add these lines at the bottom:

apc.write_lock = 1
apc.slam_defense = 0

Edit /etc/php5/fpm/pool.d/www.conf


listen =


listen = /dev/shm/php-fpm-www.sock

Below that, insert these 3 lines

listen.owner = nginx = nginx
listen.mode = 0660

Then, further down in the same file, replace these 2 lines

user = www-data
group = www-data


user = nginx
group = nginx

Save the file, PHP FPM is now complete, but it won’t work until we install nginx, so don’t worry about starting it now.

Install and Configure Nginx

Instructions based on the Nginx website.

Download the nginx secure key to verify the package

cd /tmp/
apt-key add /tmp/nginx_signing.key

Add the sources to the APT sources file by running these 2 commands (the >> is important!)

echo “deb lucid nginx” >> /etc/apt/sources.list
echo “deb-src lucid nginx” >> /etc/apt/sources.list

Download and install nginx by running

apt-get update
apt-get install nginx

When that completes, nginx will be installed, but needs configuring for WordPress.

nginx configuration files are in /etc/nginx

First, edit /etc/nginx/nginx.conf

Inside the http section , insert the following line so that when you later add varnish in front, things don’t break all over the place:

port_in_redirect off;

Next, cd to /etc/nginx/conf.d and create a new file, /etc/nginx/conf.d/drop with the contents of the drop file from GitHub

Then, replace /etc/nginx/conf.d/default.conf with the contents of the github default.conf file changing all entries for with your own domain name (there’s 3 entries, including 1 near the bottom)

Make a directory, /var/www/ and set the ownership:

mkdir -p /var/www/
chown nginx:nginx /var/www/
chmod 775 /var/www

That’s nginx configured, restart it and the PHP FPM service by running:

service nginx restart
service php5-fpm restart

Now, you’re actually ready to install WordPress!

This is pretty simple, run:

cd /tmp
tar zxvf latest.tar.gz
cd wordpress
mv * /var/www/
chown -R nginx:nginx /var/www

To configure WordPress, run:

cp /var/www/wp-config-sample.php /var/www/wp-config.php
chown nginx:nginx /var/www/wp-config.php

In a web browser, visit and copy the results

Edit /var/www/wp-config.php

and scroll down to fine the AUTH_KEY line down to NONCE_SALT, and replace them with the values you copied from the site

Then, replace the default values with the MySQL ones you chose earlier (not the root user):

define(‘DB_NAME’, ‘database_name_here’);
define(‘DB_USER’, ‘username_here’);
define(‘DB_PASSWORD’, ‘password_here’);

And once it’s done, if you’ve not had any errors and your domain name is pointing at the right IP (this is important!), then you’ll be able to visit your domain and see the WordPress configuration page at

Go through install questions, choose a sensible username and password (it’s highly recommended you change the admin user from “admin” to something else.

Go to settings then select permalinks, and choose “Custom Structure”, and paste in the value below (including the % symbols)


Then hit “Save Changes”

It’s time to create a test post, so click on “Posts” then “Add New”

Enter a title and body, then hit “Post”, and make a note of it’s friendly URL.

Run a test to see how we’re doing

100 users, 60 seconds. Timeouts, low hit rates, errors, etc. CPU flat out, seems to be the initial bottleneck.

This rush generated 632 successful hits in 1.0 min and we transferred 1.76 MB of data in and out of your app. The average hit rate of 9.81/second translates to about 847,776 hits/day.

You got bigger problems though: 34.91% of the users during this rush experienced timeouts or errors!

So the server is running, but it’s still too slow!

Next, we will enable the WordPress caching systems

Go to the wordpress admin page, then plugins, and click install new plugin.

Update Skip the W3 Total Cache plugin if you’re following this as a tutorial, it’s not been updated in ages. I’ll update this post in the future with W3 Super Cache instructions instead, but everything else should work as it is for now
Search for “W3 Total Cache”, then click “Install Now” when the search results return. When installation is complete, click “Activate Plugin”.

Go to the new “Performance” section in the menu at the left side of the page.

Scroll through the cache options, selecting “PHP APC” at each opportunity and enabling the following 2 sections:

Database Cache
Object Cache

Hit “Save All Settings” then hit “Deploy”

Rerun the test again, performance should be much improved

This rush generated 2,902 successful hits in 1.0 min and we transferred 27.59 MB of data in and out of your app. The average hit rate of 46/second translates to about 4,006,008 hits/day.

If we then up the run from 100 users to 250 users, there are still problems we need to fix:

This rush generated 4,733 successful hits in 1.0 min and we transferred 36.20 MB of data in and out of your app. The average hit rate of 72/second translates to about 6,297,653 hits/day.

You got bigger problems though: 5.49% of the users during this rush experienced timeouts or errors!

You can see the Blitz results from the Nginx And APC configuration in this PDF.

So still not perfect – Time to install varnish 3!

apt-get install varnish

Edit /etc/varnish/default.vcl replace the contents with the file default.vcl file from github.

Edit /etc/default/varnish

Change the section

DAEMON_OPTS=”-a :6081 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,256m”


DAEMON_OPTS=”-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,64m”

Next, we need to edit the nginx configuration to listen on port 8080, instead of port 80 – Varnish is going to be running on port 80 instead.

Edit /etc/nginx/conf.d/default.conf and replace

listen 80;


listen 8080;

Save the file, then run

service nginx restart
service varnish restart

Re-run the test with 100 users

Almost no CPU usage, should get perfect results

This rush generated 2,959 successful hits in 1.0 min and we transferred 28.36 MB of data in and out of your app. The average hit rate of 47/second translates to about 4,093,000 hits/day.

Re-run the blitz with 250 users

This rush generated 7,342 successful hits in 1.0 min and we transferred 70.38 MB of data in and out of your app. The average hit rate of 117/second translates to about 10,134,627 hits/day.

You can see the full final run blitz performance details in this PDF.

There it is, 10 million hits per day using WordPress on a box costing less than $20 a month, all thanks to varnish and nginx, easy!

Restart Nginx WebServer

How do I restart nginx web server under Linux?

To restart nginx web server use any one of the following command as a root user:
# /etc/init.d/nginx restart
However, recommed way is as follows which should work with any Linux distribution :
# nginx -s reload
# /usr/local/nginx/sbin/nginx -s reload