Why Haven’t You Upgraded to HTTP/2?
From a Java perspective, I’ve been the beneficiary of some pretty amazing features over the years:
- Generics (Java 5)
- Streams and Lambda Expressions (Java 8)
- Enhanced Collection Functionality (Java 9)
- Sealed Classes (Java 17)
As key features become available, I’ve been able to reduce development time as I implement features, while also seeing benefits in performance and supportability.
However, one area that seems to have lagged behind is the adoption of a key internet protocol: HTTP/2. While the second major release has been around for over nine years, migration from the 1.x version has been slower than expected.
I wanted to explore HTTP/2 to understand not only the benefits but also what it looks like to adopt this new version. In this article, we’ll look at my anecdotal experience, plus some challenges I found, too.
About HTTP/2
HTTP/2 was released in May 2015 and included the following improvements over the prior version of HTTP:
- Multiplexing: Allows multiple requests and responses to be sent over a single connection
- Header compression: Reduces the overhead of HTTP headers by using compression
- Server push: Enables servers to send resources to a client proactively
- Resource prioritization: Allows consumers to specify the importance of given resources, affecting the order in which they’re loaded
- Binary protocol: Provides an alternative to the text-based format of HTTP/1.x
Additionally, HTTP/2 is backward compatible with HTTP/1.x.
Common Use Cases for HTTP/2
Below are just some of the strong use cases for HTTP/2:
- A full-stack application that contains a chatty consumer, consistently communicating with the service tier
- An application that relies heavily on content being stored inside the HTTP headers
- A solution that is dependent on server-initiated events to broadcast updates to consumers
- A client application that can benefit from providing prioritization instructions to the underlying service
- A web client that requires large amounts of data to be retrieved from the service tier
Migrating to HTTP/2 for any of these use cases could provide noticeable improvements from a consumer perspective.
What’s Involved With HTTP/2 Adoption?
When I think about a lower-than-expected adoption rate of 45%-50% (as noted in this Cloudflare blog), I wonder if developers believe the upgrade to HTTP/2 won’t be easy. But I don’t get why they feel that way. After all, HTTP/2 is backwards compatible with HTTP/1.x.
Using Spring Boot 3.x (which requires Java 17+ and uses the default Jetty server) as an example, upgrading to HTTP/2 is actually kind of easy. The biggest hurdle is making sure you are using SSL/TLS — which is honestly a good idea for your services anyway.
server.port=8443
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=<your_password_goes_here>
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=<your_alias_goes_here>
With SSL/TLS in place, you just need to enable HTTP/2 via this property:
server.http2.enabled=true
At this point, your service will start and utilize HTTP/2. By default, all of the features noted above will be ready for use.
Is that all there is to it?
But Wait … There’s More to the Story
Depending on where your service is running, the effort to upgrade to HTTP/2 might not yield the results you were expecting. This is because network infrastructure often stands between your service and the consumers wanting to take advantage of HTTP/2 greatness. That layer needs to fully support HTTP/2 as well.
What does this mean? It means your service could receive the request and provide an HTTP/2 response, only for a router to downgrade the protocol to HTTP/1.1. Here’s the big takeaway: before you get all excited about using HTTP/2 and spend time upgrading your services, you should confirm that your network layer supports it.
Recently, Heroku announced support of HTTP/2 at the router level. They’re addressing this exact scenario, and HTTP/2 is now available in a public beta. The illustration below demonstrates how they make HTTP/2 service responses available to consumers:
This initial push from Heroku makes it possible for service developers like me to build applications that can take advantage of HTTP/2 features like header compression and multiplexing. This means faster delivery to consumers while potentially reducing compute and network loads.
If your cloud provider doesn’t have infrastructure that supports HTTP/2, requests to your HTTP/2-enabled service will result in an HTTP/1.x response. As a result, you won’t get the HTTP/2 benefits you’re looking for.
Challenges With HTTP/2
While my own experience of upgrading my Spring Boot services to leverage HTTP/2 hasn’t run up against any significant challenges — especially with support now at the cloud provider network level — I am reading more about others who’ve struggled with the adoption.
Based on some of the customer experiences I’ve found, here are some items to be aware of during your journey to HTTP/2:
- Increase in compute cost: These features can lead to more processing power than what you may have needed for HTTP/1.x.
- Impact on other portions of the response: After adding SSL/TLS to your service, expect that more time will be required to perform this layer of processing.
- Advanced features can be misconfigured: You’ll want to understand concepts like multiplexing, stream prioritization, flow control, and header compression, as these items can impact performance in a negative manner if not configured correctly.
If your path to production includes dev, QA, and staging environments, you should be able to identify and mitigate any of these hurdles long before your code reaches production.
Conclusion
My readers may recall my personal mission statement, which I feel can apply to any IT professional:
“Focus your time on delivering features/functionality that extends the value of your intellectual property. Leverage frameworks, products, and services for everything else.”
— J. Vester
Upgrading to HTTP/2 certainly adheres to my mission statement by giving service owners features like multiplexing, header compression, resource prioritization, and binary responses — all of which can impact the overall performance of a service or the consuming application.
At the same time, cloud providers who support HTTP/2 — like Heroku — also get credit for adhering to my mission statement. Without this layer of support, applications that interact with these services wouldn’t be able to take advantage of these benefits.
When I reflect on my personal experience with Java, I can’t imagine a world where I am writing Java code without using generics, streams, lambdas, enhanced collections, and sealed classes. All of these features are possible because I took the time to see the benefits and perform the upgrade.
The question really isn’t if you should upgrade to HTTP/2, but rather which upcoming development iteration will cover this enhancement.
Have a really great day!