Optimizing https performance on Ubuntu/Trusty/Nginx

At the time of writing, Ubuntu Trusty LTS is the latest LTS version of Ubuntu out there so perhaps it is not surprising that the version of Nginx that comes with it is not the absolute latest. Still Ubuntu’s nginx/1.4.6 is a long way behind the latest nginx/1.6.2. Functionally, they both serve the basics fine but in trying to optimize https performance, I realised the upgrade is well worth it.

Here are the steps to upgrade

Add these contents to /etc/apt/sources.list.d/nginx.list file:

deb http://nginx.org/packages/ubuntu/ trusty nginx
deb-src http://nginx.org/packages/ubuntu/ trusty nginx

Then run the following commands:

apt-get remove nginx nginx-full nginx-common nginx-core
apt-get update
apt-get install nginx

Installing directly over is supposed to work but you can get weird errors with /etc/logrotate.d/nginx so it is better to remove first.

Just by updating to the latest, initial SSL handshake latency reduced by 50% in my test case! (600ms to 400ms for a Dallas client connecting to the HK server).

Reducing initial SSL handshake is important for that first visitor experience but it is equally important to maximise performance for subsequent visits. Here, one still needs to get hands-on with the config. Here is my result:

server {
listen 80;
listen 443 ssl spdy;
server_name gainstrack.com;
rewrite ^/(.*) https://www.gainstrack.com/$1 permanent;

ssl_certificate /etc/nginx/gainstrack.com.unified.crt;
ssl_certificate_key /etc/nginx/gainstrack.com.private.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";

Substitute server_name/ssl_certificate/ssl_certificate_key for your own server and ignore the rewrite rule, which is for AngularJS. The important optimizations here are

  • Enabling the spdy protocol, along side https. This is Google’s enhancement to further reduce latency in modern browsers
  • Choosing the “best” set of ciphers available (at the cost of excluding IE8 and below. I don’t care because my Angular site only supports later IE versions anyway). The “best” includes forward secrecy protocols that are not only more secure but offer lower latency because some parts of the expensive SSL handshake can be skipped
  • Enabling SSL session caching so that most browers don’t need to do the expensive SLL handshake when reconnecting.

Finally, with everything optimized for performance close to unsecure HTTP, the Strict-Transport-Security header will encourage modern browsers to treat HTTPS as the default secure way to connect to the website.

The result? Almost the best possible performant nginx setup with this version of nginx and a nice A grade at SSLLabs gainstrack.com analysis.

https://www.gainstrack.com is now secure.

https enabled for gainstrack.com

https://www.gainstrack.com is now live. At some point it should become default. This is important so that passwords sent to the site are encrypted when logging in.

On a side note, I find it ironic that sending passwords to websites on unencrypted http raises no warnings while sending to encrypted self-signed websites raises all sorts of alarm bells. How is the former better??

Fortunately, setting up https is easier than it used to be. I thank Startssl for their free basic SSL certificates and this blog post for explaining how to set it up for the nginx server. According to the SSLlabs report, the site is all good to go!

Time to update the links for my training log to https://www.gainstrack.com/user/KevinTam

The lessons of HCI and User Testing

So one of my side projects is producing a mobile app for logging workouts into Gainstrack. The prototype has been under development for the past couple of months and reached a stage where I was very comfortable dogfooding it for logging my own workouts on my phone.

Before unleashing it to a wider audience, HCI training kicked in and thought I’d run a user test where I set a user some tasks to accomplish on the mobile app, never having used the app before, while I quietly watched and took notes.

The participant in this case is my fiance… a largely non-technical user who is a regular user of Android/iPhone apps who is familiar with some strength training. Her tasks were to

  • Attempt to log a typical workout
  • Attempt to make amendments to a workout
  • Register her details with the app

I already took these tasks for granted but I got a plethora of useful feedback from this single participant.

  • The first menu item under the Home menu item was the Plate Calculator. She immediately started playing with that rather than doing a workout
    • Lesson: Make Log Workout the first menu item
  • She understood “Enter the barbell weight” as the loaded weight
    • Lesson: Make the text “Enter the empty barbell weight”
  • Back to logging, she said that Account should therefore be the top item because surely you need to register before logging.
    •  Actually, my site supports starting a log without registering but that fact she takes registration for granted, maybe that could be highlighted sooner
  • Adding an exercise was non-obvious. The layout of exercise/add/quick didn’t make sense for her. She couldn’t figure out how to add a typed exercise (press the add button!). So the layout is changing

  • She can’t add her Running exercises… weights only for now. Looks like I can’t convert her yet!
  • The keyboard jumps around a lot when adding new sets. Actually, this bugs me too, it’s a real problem that needs fixing
  • Pressing Add when no exercise is typed does nothing. This is double confusing when she didn’t know what Add was supposed to do anyway
  • Cancel button cleared the screen rather than cancelling
  • The “More Options” and Delete workout were oddly placed, according to her. It’s going to move

As with many HCI user tests, the feedback was both surprising and usefully constructive. Lots of minor interface improvements are on the way! A good learning exercise all around.

Oh, and I submitted my first workout from my mobile app proper… coming very soon.