I decided to try out this suggestion from Optimizing NGINX TLS Time To First Byte (TTFB) ( which I mentioned at the end of 2013 ):
After digging through the nginx source code, one stumbles onto this gem. Turns out, any nginx version prior to 1.5.6 has this issue: certificates over 4KB in size incur an extra roundtrip, turning a two roundtrip handshake into a three roundtrip affair – yikes. Worse, in this particular case we trigger another unfortunate edge case in Windows TCP stack: the client ACKs the first few packets from the server, but then waits ~200ms before it triggers a delayed ACK for the last segment. In total, that results in extra 580ms of latency that we did not expect.
I’ve been using Nginx 1.4.x from the Ubuntu package collection on this site. A few webpagetest.org runs showed that HTTPS negotiation was taking more than 300ms on the initial request. After updating to Nginx 1.5.13 more tests showed HTTPS negotiation was down around 250ms.
The 50ms savings isn’t nearly as dramatic as the worst case scenario described in the quote above, but I’ll take it.
9 replies on “Update Nginx For Better HTTPS Performance”
Hi Joseph!
Excellent work! It’s nice how many problems updating to the mainline version of Nginx can solve for you. It’s also great to see how many WordPress folks are learning about and improving SSL performance.
I took a quick look at your setup via SSL Labs and have a few suggestions. It looks like you are including the root cert in your cert package. This can lead to extra RTT because of TCP Slow Start. Your initial congestion window might not be able to handle the size of the cert and therefore incur extra RTT. Removing the cert (which is available in all browsers already) could reduce the SSL handshake time some more.
You may also want to check and ensure that the “ssl_buffer_size” is set to not overflow the buffer causing extra RTT.
While not performance related, it looks like you are using some insecure ciphers in your cipher suite. I’d recommend a list of different ciphers that are secure and provide PFS.
Finally, since you are running 1.5.13 with the SPDY module compiled into it, you might as well use it! You get a whole host of performance benefits with it (although it has no impact on the SSL negotiation other than you only have to do it once per page view). You only need to add a few changes to your Nginx config file:
1. Enable SPDY
2. Announce SPDY
Enabling SPDY will remove all of the extra purple and orange in your waterfall for the low cost of two lines of config.
Thanks for the feedback. I am bundling the root cert, I could probably get away with just including the intermediate cert, which I haven’t tried yet.
I did try a few values for the ssl_buffer_size, in my tests I found that they didn’t make any difference. In terms of ciphers, I’m trying out new combinations all the time. I’m never quiet happy with the combination of performance, security, and client support. My SSL Labs score flops around all over the place as a result š
SPDY is something that I’ll look at enabling the next time I tweak my config. For this particular upgrade I only wanted to limit the number of changes to make it easier to see what their individual impact was.
I’d be interested to see what happens if you remove the root cert and continue to change the buffer size. You might lose a RT.
I totally understand. The suite I linked to has worked really well. I used it for the SSL setup we are using at The Theme Foundry. It hits the sweet spot between performance, security and compatibility.
You will love it once you get SPDY installed! The waterfall becomes a work of art š
I’m trying out that cipher list now. Tests so far have been good, performance doesn’t seem to have significantly changed ( at least when browsing with Chrome ) and security is definitely better.
Awesome! Glad to hear it. I wouldn’t expect performance improvements with a change to the cipher list; although, I suppose there could be micro improvements with some browsers I suppose.
Was mostly looking to see if they got significantly worse.
I tried it with the root cert removed. It obviously reduced the cert size ( from 3625 bytes to 2543 bytes ), but didn’t appear to have any significant improvement for performance.
Interesting. It’s still nice to remove the extra bloat and along with some of the other optimizations, you should hopefully be able to improve the performance.
[…] Tollman suggested I try out SPDY with my updated Nginx install. While I’m sad at the idea of giving up a plain text HTTP API, […]