I had a chance to deploy one of my running websites on another virtual machine.
I wanted to improve performance as customers are paying for the product and wanted to give a faster experience.
On the old site I used Apache with PHP mod apache to run the site. On the new site I went with Nginx and PHP-FPM.
The Server Setups
Both websites use the Yii Framework on PHP with a MySQL database. There has been some performance tweaks on the Old Site. The new site I left everything standard.
Old Site:
- 2GB RAM (free 222MB)
CPU(s): 2
- Site shared – vhosts with a few other sites
- HTTPS Enabled (letencrypt)
*PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
- Server hosted in Nederlands (Testing from South Africa)
New Site:
- 2GB RAM (Free 1161MB)
CPU(s): 2
- Site dedicated, not other site on server
- No HTTPS
PRETTY_NAME="Ubuntu 18.04.4 LTS"
- Server hosted in South Africa (Testing from South Africa)
Method
The method for the performance test is as follows.
- Enable response time logging in the access logs of both apache and nginx – I wrote a post on this with apache and there are docs online for nginx
- Browsing Test – I will browse as a non logged in and logged in user on both sites in isolation. The statistics of response times will be recorded from the user’s perspective in the browser and from the log response times.
- WebPage Test – I will use Web Page Test to compare both sites for a few pages.
- Load Test – I will test concurrent load with locustio
- Sitespeed.io Test – Test using sitespeed.io open source sitespeed testing utility
This will not be a scientific comparison – purely anecdotal
Browsing Test
Page | Nginx + PHP-FPM (ms) | Apache + ModPHP (ms) | Difference |
---|---|---|---|
Home Page | 1380 | 1660 | 20% |
Contact Us | 1060 | 1310 | 24% |
About Us | 997 | 1280 | 28% |
Login (POST) | 1410 | 7550 | 435% |
Portfolio (Db intentensive) | 1920 | 6960 | 263% |
Calculator | 946 | 1310 | 38% |
Chart (TTFB) | 105 | 348 | 231% |
From the chart above it is safe to say that without a shadow of a doubt, the new site is faster.
Naturally the server being much closer helps. Instead of 9354km the new server is about 50km away. The average latency on a ping is 187 ms to the old server and about 12ms to the new one.
WebPage Test
I tested both sites from south africa, here are the screenshots and relevant info below:
WebPageTest Metric | Nginx + PHP-FPM | Apache + ModPHP |
---|---|---|
First Byte | 102 | 895 |
Speed Index | 769 | 1660 |
Document Complete Time | 3850 | 3353 |
Document Complete Requests | 36 | 33 |
Fully Loaded Time | 4746 | 4087 |
Fully Loaded Requests | 48 | 46 |
Surprisingly the new website performed worse (in total). It was faster to first byte but full load was worse. Furthermore no caching and webpagetest does not like that.
WebPageTest Metric | Nginx + PHP-FPM | Apache + ModPHP |
---|---|---|
First Byte | 126 | 913 |
Speed Index | 800 | 1681 |
Document Complete Time | 6825 | 2989 |
Document Complete Requests | 18 | 16 |
Fully Loaded Time | 6869 | 3215 |
Fully Loaded Requests | 19 | 17 |
The results of this were also pretty annoying. It seems that webpagetest wants me to cache static content, gzip assets and use a CDN. Then it will be happy.
Let me add gzip and static caching to nginx and see.
Just uncomment the gzip section in the default nginx.conf
.
After adding updaing it is looking a bit better:
I then removed the twitter feed and things were better:
Old Site:
New Site:
Load Test
I created a test to make some GET requests against the server – while not logged in. The test has users spawn at 1 a second.
The new site performed as follows
So it can run stably from 80 to 100 RPS.
The old site performed terribly. When I got up to 2 RPS all the other sites monitoring was saying it was down. It was weird that the RPS didn’t grow according to users as fast with the old site – perhaps locust knows it couldn’t handle that spawn rate.
Sitespeed.io
To do a more comprehensive test I employed sitespeed.io. I then ran the test against both sites are here are the results…
The Old Mod-PHP and Apache site
The New PHP-FPM and Nginx site
Update Adding HTTP/2
I was using the default nginx config that is HTTP/1.1
, so I updated it to serve with HTTP/2
Now, I have switched over the performance site to be the current site.
- First bytes is a bit slower
0.192s
vs0.095s
on the HTTP/1.1 version - Start render is also about 100ms faster at
0.400s
vs0.500s
on the HTTP/2 site - Document complete and fully loaded is however much faster on
HTTP/2
– even with the 100ms handicap. It is about300ms
faster – probably due to HTTP/2 multiplexing of asset acquisition.
Conclusion
Some tests were conclusive – others were still in the balance.
From a load testing and user initial response view – the new site clearly wins. The biggest gain comes more from concurrent users and handling load. Another significant bit was moving the server closer to the users.
The PHP-FPM with Nginx site can handle 40 or more times more load than the other site and has a faster response even with the 200ms handicap.
Next Steps
The next steps to take would be to look at how to maximise performance with nginx and php-fpm