What are SPDY and HTTP/2 and How to Enable Them on Nginx

One of the core technologies powering the web is HTTP. Unfortunately HTTP/1.1 was designed for static HTML sites and was last updated around 1999. The web today has changed quite a lot. Websites are more and more dynamic, contains a lot of resources. In this tutorial I will explain what are SPDY and HTTP/2 and how to enable them on Nginx and also how to test them.

SPDY

In 2009 Google introduced a new protocol called SPDY (pronounced speedy). SPDY offers three key improvements over HTTP/1.1.

1. Header Compression

Every HTTP request and response include a sizeable amount of data in the header. There’re a lot of repetitive meta data (user agent and cookies) in the header. HTTP/1.1 can only compress the actual content and can not compress the header. SPDY significantly shrink the header size. SPDY supports sending header once for an entire connection instead of sending them for every repetitive single connection.

2. Parallel Requests

HTTP is a message-based protocol. Once you have established a TCP connection and you send an HTTP request you have to site there and wait for response to arrive before you can send the next request. Each such request requires at least one round trip between the browser and the server which can take hundreds of milliseconds. This is a significant delay. If one of the responses was slow, it will delay all the other requests. This is called head-of-line blocking. Although you can open multiple concurrent connections to send multiple requests at the same time, but modern browsers usually limit to 4~8 concurrent connections per host.

In HTTP, the relationship between the request message and the response message is implicit. The server does not explicitly say I’m the response to that request. You can only identify it’s the response the that request because the response follows that request in order.

SPDY offers true multiplexing. With SPDY you can send as many requests as you like at a single connection and get the responses in whatever order. So browsers don’t have to open multiple connections per hostname to send multiple requests. SPDY enables them to open one connection per hostname. This will also reduce the load on the server because less connections means less sockets are open on the server.

3. Server Push and Server Hint

In HTTP, all communications between the browser and server is initiated by the browser. If the server has something to say, it actually has to wait for the browser to ask for the information. When the browser request HTML, the server knows the browser needs the associated css, JavaScript or image which needs to be fetched by browser in order to fully render the page. But in HTTP the server has to wait for the browser to request those css, JavaScript and image.

With SPDY, the server is able to proactively push data without the browser requesting it.

In some cases, server push may be wasteful. For instance maybe the browser already had the css file in its cache and wouldn’t download it again. SPDY had a lite version of server push called server hint which means the server only offers suggestions to the browser but the request is still made by the client.

The following web performance best practices are no longer needed with SPDY, greatly reducing developer’s workload.

  • CSS Sprite
  • Inline Image
  • Sharding to improve parallel requests.
  • CSS/JavaScript Concatenation

Limitations

SPDY is great but it still has some limitations.

  1. The first is that it limits to HTTPS.
  2. SPDY communicates separately with each host. The browser may have to communicates with multiple hosts in order to fully render a webpage. Even if all of them support SPDY, the browser still have to open one connection per host. Multiplexing can only occur on a per host basis.

How to Enable SPDY On Nginx

As said before, you need to enable HTTPS in order to use SPDY. Fortunately now you can easily get a free SSL/TLS certificate from Let’s Encrypt. If you have not yet enabled HTTPS, please use the following link to get a free SSL/TLS certificate.

A oveview of HTTPS encryption and Let’s Encrypt SSL/TLS certificate deployment with Nginx

If you have enabled HTTPS, check if Nginx is compiled with SPDY module

sudo nginx -V

If you see the following text, then SPDY module is included in your Nginx installation.

--with-http_spdy_module

Configure server block file

sudo vi /etc/nginx/conf.d/yourdomain.conf

or

sudo vi /etc/nginx/sites-available/yourdomain.conf

In the server section, add spdy after listen 443 ssl.

server {
    listen 443 ssl spdy;
    server_name www.linuxbabe.com;

    ssl_certificate /etc/ssl/fullchain.pem;
    ssl_certificate_key /etc/ssl/privkey.pem;

......

Then save and close the file. Reload Nginx configuration.

sudo service nginx reload

or

sudo systemctl reload nginx

And you are done. Very easy!

As of Nginx 1.9.5, ngx_http_spdy_module was superseded by ngx_http_v2_module. So if you are using a version higher than 1.9.5, you don’t need to enable SPDY. See the following text to learn HTTP/2 and how to enable it with Nginx.

HTTP/2

HTTP/2 is based on SPDY. The HTTP/2 specification was published as RFC 7540 in May 2015. HTTP/2 has the same semantics as HTTP/1.1. HTTP/2 is binary, instead of textual. HTTP/2 separate response into header frame and data frame.

Improvements over SPDY

HPACK Compression

HPACK is a faster and smarter way to compress header. It’s specifically designed for this work. The ngx_http_spdy_module of Nginx disables header gzip compression by default because it can be attacked by CRIME.

Requires No SSL/TLS

HTTP/2 protocol itself requires no SSL/TLS connection. But the implementation in all major browser vendors Firefox, Chrome, Opera say they will require TLS.

 ALPN

With ALPN the browser and the server can establish an HTTP/2 connection from the get-go instead of establishing a HTTP/1.1 connection first and then negotiate an HTTP/2 connection. ALPN is an improvement over NPN which is used by SPDY.

Enable HTTP/2 on Nginx

As of version 1.9.5, Nginx supports HTTP/2, so you have to install a Nginx version at least 1.9.5. I also suggest compiling the latest Nginx with ngx_pagespeed module, but it’s up to you. Use the following link to see how they’re done.

Install latest version of Nginx on Ubuntu server

Boost site speed by compiling latest Nginx version with ngx_pagespeed module on Ubuntu server

Like SPDY, it’s really simple to enable HTTP/2 on Nginx. Check if Nginx is compiled with HTTP/2 module

sudo nginx -V

Since your Nginx version is at least 1.9.5, you should see the following text in the output.

--with-http_v2_module

Then configure server block file

sudo vi /etc/nginx/conf.d/yourdomain.conf

or

sudo vi /etc/nginx/sites-available/yourdomain.conf

In the server section, add http2 after listen 443 ssl.

server {
    listen 443 ssl http2;
    server_name www.linuxbabe.com;

    ssl_certificate /etc/ssl/fullchain.pem;
    ssl_certificate_key /etc/ssl/privkey.pem;

......

Then save and close the file. Reload Nginx configuration.

sudo service nginx reload

or

sudo systemctl reload nginx

And you are done. Very easy!

How to Check if HTTP/2 is Working on Your Website

Go to https://tools.keycdn.com/http2-test. And enter your domain. Cloudflare has an excellent post about tools for testing and debugging HTTP/2.

Rate this tutorial
[Total: 2 Average: 3.5]