HTTP/2 (or “H2” as the cool kids call it) has been ratified for months, and browsers already support or have committed to supporting the protocol. Everything we hear tells us that the new version of HTTP will provide significant performance benefits while requiring little to no change to our applications—all the problems with HTTP/1.x have seemingly been addressed; we no longer need the “hacks” that enabled us to circumvent them; and the Internet is about to be a happy place at last.
But maybe we should put the pom-poms down for a minute. Deploying HTTP/2 may not be as easy as it seems since the protocol brings with it new complications and issues. Likewise, the new features the spec introduces may not work as seamlessly as we hope. Hooman Beheshti examines HTTP/2’s core features and how they relate to real-world conditions, discussing the positives, negatives, new caveats, and practical considerations for deploying HTTP/2.
Topics include:
The single-connection model and the impact of degraded network conditions on HTTP/2 versus HTTP/1
How server push interacts (or doesn’t) with modern browser caches
What HTTP/2’s flow control mechanism means for server-to-client communication
New considerations for deploying HPACK compression
Difficulties in troubleshooting HTTP/2 communications, new tools, and new ways to use old tools
10. A single connection
• single, long-lasting TCP connection
• Theoretically, this means better congestion
management between peers
• TLS (with ALPN)
• Connection reuse across domains (same IP and cert)
13. Streams
• Virtual channels for communication
– Translate roughly to a request/response exchange
– Client or server can initiate or terminate
• Stream IDs:
– Client: odd; server: even; 0: reserved
– Each ID has to be larger than the ones before it initiated
by the endpoint
– Cannot be reused
16. GET /thing HTTP/1.1
Host: www.example.com
User-Agent: Some_user_agent
HTTP/1.1 200 OK
Server: some_server
Content-Type: text/html
Content-Length: 1000
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
Request Response
17. GET /thing HTTP/1.1
Host: www.example.com
User-Agent: Some_user_agent
HTTP/1.1 200 OK
Server: some_server
Content-Type: text/html
Content-Length: 1000
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
HEADERS
Request Response
18. GET /thing HTTP/1.1
Host: www.example.com
User-Agent: Some_user_agent
HTTP/1.1 200 OK
Server: some_server
Content-Type: text/html
Content-Length: 1000
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
HEADERS
HEADERS
Request Response
19. GET /thing HTTP/1.1
Host: www.example.com
User-Agent: Some_user_agent
HTTP/1.1 200 OK
Server: some_server
Content-Type: text/html
Content-Length: 1000
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
html html html html html html
DATA
DATA
DATA
DATA
DATA
DATA
HEADERS
HEADERS
Request Response
20. DATA Carries request or response data
HEADERS
Carries request/response headers/trailers; can initiate a
stream
PRIORITY Indicates priority of a stream
RST_STREAM Terminates a stream
SETTINGS Defines parameters for the connection only
PUSH_PROMISE Signals peer for server push
PING Maintenance frame for checking RTT, connection, etc
GOAWAY For shutting down a connection
WINDOW_UPDATE Frame responsible for flow control adjustments
CONTINUATION Extends a HEADERS frame and can carry more headers
21. DATA Carries request or response data
HEADERS
Carries request/response headers/trailers; can initiate a
stream
PRIORITY Indicates priority of a stream
RST_STREAM Terminates a stream
SETTINGS Defines parameters for the connection only
PUSH_PROMISE Signals peer for server push
PING Maintenance frame for checking RTT, connection, etc
GOAWAY For shutting down a connection
WINDOW_UPDATE Frame responsible for flow control adjustments
CONTINUATION Extends a HEADERS frame and can carry more headers
65. Real pages
• 8 pages (from 8 real sites)
• 16 bandwidth/latency combinations
– Each with 0%, 0.5%, 1%, 2% PLR
• Firefox and Chrome, TLS only, collect all metrics
• 300-400 runs with each combination
66. Real pages
• 8 pages (from 8 real sites)
• 16 bandwidth/latency combinations
– Each with 0%, 0.5%, 1%, 2% PLR
• Firefox and Chrome, TLS only, collect all metrics
• 300-400 runs with each combination
67.
68. Analysis
• 3 Types of pages, # of resources h1àh2:
– ~75% or higher
– ~half
– ~25% or lower
• 2 profiles (0%, 0.5%, 1%, 2% PLR):
– “Broadband”: 5Mbps/1Mbps/40ms
– “Slow 3G”: 780Kbps/330Kbps/200ms
• 3 Metrics
– Document Complete
– DOM Content Loaded Start
– Speed Index
100. Trends?
• Metrics later in the page seem to get affected more
by packet loss (?)
• Lots of exceptions
– Sometimes h2 holds up even under loss conditions
– Sometimes h1 wins even when there’s no loss
• Firefox and Chrome don’t always behave the same
105. Caution!
• we’re not going to draw big conclusions, other than:
– Packet loss seems to matter
– h2 isn’t always faster!
• This was all simulated
– PLR is different in the real world
– Users have a mix of connection profiles
– Nothing beats real world data
• Your mileage may (and will) vary
115. Server push basics
• Ability to “push” a resource to the client before
the client requests it
– And before the client knows it needs it
– Only servers can push
• Hop-by-hop
118. connection
HEADERS (sid=1)
GET /index.html
time
DATA (sid=2) DATA (sid=1) DATA (sid=2)
DATA (sid=2) DATA (sid=2)HEADERS (sid=2)
PUSH_PROMISE(sid=1)
Promised sid=2
GET /css1.css
<request headers>
DATA (sid=1) DATA (sid=1) DATA (sid=1)HEADERS (sid=1)
119.
120.
121. Server Push
• What do we push?
– Outside the scope of the protocol
• Push and browser caches don’t necessarily play
well together
– RST_STREAM ?
– Even if the browser rejected, it’s too late
129. Push during server think time
• Push assets to the browser while the server is
“thinking”
– Backend processing
– Time to deliver HTML from origin through a CDN
130.
131. Push during server think time
• Push assets to the browser while the server is
“thinking”
– Backend processing
– Time to deliver HTML from origin through a CDN
• https://blog.yoav.ws/being_pushy/
• This isn’t a trivial thing to do; ask your CDN
about support
133. We still have some questions
• What do we push?
– Still unclear…
– https://docs.google.com/document/d/
1K0NykTXBbbbTlv60t5MyJvXjqKGsCVNYHyLEXIxYMv0/
edit
• What if it’s already in the browser cache?
– H2O: CASPER
– Cache Digests:
• https://tools.ietf.org/html/draft-ietf-httpbis-cache-digest-00
136. HPACK (RFC 7541)
• Addresses the header bloat problem
• Two primary mechanisms
– All headers (name=value) are Huffman encoded
– Indexed tables at each peer
137. Tables
• Static table
– Defined by the RFC, never changes
• Dynamic table
– Built during the connection and maintained by each
side
– FIFO
143. HPACK – things to know
• Default size is 4K
– For the entire dynamic table
– Site-wide headers proposal:
• https://tools.ietf.org/html/draft-nottingham-site-wide-headers-00
• Compression context is set per connection
– New connection starts from scratch with static table and builds new dynamic table
• An attack vector
– https://www.imperva.com/docs/Imperva_HII_HTTP2.pdf
• Can’t turn it off
– Without it, pipelining would be very difficult
146. HPACK – things to know
• Default size is 4K
– For the entire dynamic table
– Site-wide headers proposal:
• https://tools.ietf.org/html/draft-nottingham-site-wide-headers-00
• Compression context is set per connection
– New connection starts from scratch with static table and builds new dynamic table
• An attack vector
– https://www.imperva.com/docs/Imperva_HII_HTTP2.pdf
• Can’t turn it off
– Without it, pipelining would be very difficult
157. Summary and takeaways
• h2 is complicated, but hopefully better for us going forward
– Browser protocol?
• Not everything will be as easy/fast as we’d like
• We still have a lot of learning to do
• We need to start thinking about how to build applications to best
leverage the new protocol
• You can help!