See also

HTTP/2 is the evolution of the world's most successful application layer protocol, HTTP.
It focuses on making more efficient use of network resources. It does not change the fundamentals
of HTTP, the semantics. There are still request and responses and headers and all that. So, if
you already know HTTP/1, you know 95% about HTTP/2 as well.

But, as RFC do, it's not really a good thing to read first. It's better to first understand
what a thing wants to do and then read the RFC about how it is done. A much
better document to start with is http2 explained
by Daniel Stenberg, the author of curl. It is available in
an ever growing list of languages, too!

Too Long, Didn't read: there are some new terms and gotchas that need to be kept in mind while reading this document:

HTTP/2 is a binary protocol, as opposed to HTTP 1.1 that is plain text. The latter is meant to be human readable (for example sniffing network traffic) meanwhile the former is not. More info in the official FAQ question.

h2 is HTTP/2 over TLS (protocol negotiation via ALPN).

h2c is HTTP/2 over TCP.

A frame is the smallest unit of communication within an HTTP/2 connection, consisting of a header and a variable-length sequence of octets structured according to the frame type. More info in the official documentation section.

A stream is a bidirectional flow of frames within the HTTP/2 connection. The correspondent concept in HTTP 1.1 is a request/response message exchange. More info in the official documentation section.

HTTP/2 is able to run multiple streams of data over the same TCP connection, avoiding the classic HTTP 1.1 head of blocking slow request and avoiding to re-instantiate TCP connections for each request/response (KeepAlive patched the problem in HTTP 1.1 but did not fully solve it).

The HTTP/2 protocol is implemented by its own httpd module, aptly named
mod_http2. It implements the complete set
of features described by RFC 7540 and supports HTTP/2 over cleartext (http:), as
well as secure (https:) connections. The cleartext variant is named 'h2c',
the secure one 'h2'. For h2c it allows the direct
mode and the Upgrade: via an initial HTTP/1 request.

One feature of HTTP/2 that offers new capabilities for web developers is
Server Push. See that section on how your web application
can make use of it.

mod_http2 uses the library of nghttp2
as its implementation base. In order to build mod_http2 you need at least version 1.2.1 of
libnghttp2 installed on your system.

When you ./configure you Apache httpd source tree, you need to give it
'--enable-http2' as additional argument to trigger the build of the module.
Should your libnghttp2 reside in an unusual place (whatever that is on your
operating system), you may announce its location with '--with-nghttp2=<path>'
to configure.

While that should do the trick for most, they are people who might prefer a statically
linked nghttp2 in this module. For those, the option --enable-nghttp2-staticlib-deps
exists. It works quite similar to how one statically links openssl to mod_ssl.

Speaking of SSL, you need to be aware that most browsers will speak HTTP/2 only on https:
URLs, so you need a server with SSL support. But not only that, you will need a SSL library
that supports the ALPN extension. If OpenSSL is the library you use, you need
at least version 1.0.2.

This allows only HTTP/1 on connections, except SSL connections to test.example.org
which offer HTTP/2.

Choose a strong SSLCipherSuite

The SSLCipherSuite needs to be configured with a strong TLS cipher suite. The current version of mod_http2 does not enforce any cipher but most clients do so. Pointing a browser to a h2 enabled server with a inappropriate cipher suite will force it to simply refuse and fall back to HTTP 1.1. This is a common mistake that is done while configuring httpd for HTTP/2 the first time, so please keep it in mind to avoid long debugging sessions! If you want to be sure about the cipher suite to choose please avoid the ones listed in the HTTP/2 TLS blacklist.

The order of protocols mentioned is also relevant. By default, the first one is the
most preferred protocol. When a client offers multiple choices, the one most to the
left is selected. In

Protocols http/1.1 h2

the most preferred protocol is HTTP/1 and it will always be selected unless a
client only supports h2. Since we want to talk HTTP/2 to clients that
support it, the better order is

Protocols h2 h2c http/1.1

There is one more thing to ordering: the client has its own preferences, too. If
you want, you can configure your server to select the protocol most preferred by
the client:

ProtocolsHonorOrder Off

makes the order you wrote the Protocols irrelevant and only the client's
ordering will decide.

A last thing: the protocols you configure are not checked for correctness
or spelling. You can mention protocols that do not exist, so there is no need
to guard Protocols with any IfModule checks.

Other clients, as well as servers, are listed
on the Implementations wiki,
among them implementations for c, c++, common lisp, dart, erlang, haskell, java, nodejs, php,
python, perl, ruby, rust, scala and swift.

Several of the non-browser client implementations support HTTP/2 over cleartext, h2c. The
most versatile being curl.

The HTTP/2 protocol allows the server to PUSH responses to a client it never
asked for. The tone of the conversation is: "here is a request that you
never sent and the response to it will arrive soon..."

But there are restrictions: the client can disable this feature and the
server may only ever PUSH on a request that came from the client.

The intention is to allow the server to send resources to the client that
it will most likely need: a css or javascript resource that belongs to a html
page the client requested. A set of images that is referenced by a css, etc.

The advantage for the client is that it saves the time to send the request which
may range from a few milliseconds to half a second, depending on where on the
globe both are located. The disadvantage is that the client may get sent
things it already has in its cache. Sure, HTTP/2 allows for the early cancellation
of such requests, but still there are resources wasted.

To summarize: there is no one good strategy on how to make best use of this
feature of HTTP/2 and everyone is still experimenting. So, how do you experiment
with it in Apache httpd?

If the connection supports PUSH, these two resources will be sent to the
client. As a web developer, you may set these headers either directly in
your application response or you configure the server via

If you want to use preload links without triggering a PUSH, you
can use the nopush parameter, as in

Link </xxx.css>;rel=preload;nopush

or you may disable PUSHes for your server entirely with the directive

H2Push Off

And there is more:

The module will keep a diary of what has been PUSHed for each connection
(hashes of URLs, basically) and will not PUSH the same resource twice. When
the connection closes, this information is discarded.

There are people thinking about how a client can tell a server what it
already has, so PUSHes for those things can be avoided, but this is all
highly experimental right now.

Another experimental draft that has been implemented in mod_http2
is the
Accept-Push-Policy Header Field where a client can, for each request, define
what kind of PUSHes it accepts.

Notice:This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed again by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Freenode, or sent to our mailing lists.