alt text is a site I maintain which uses Nginx as a reverse proxy to Kestrel.

I’ve implemented HTTP/2 on Nginx, and passes HTTP request version information request headers to Kestrel to allow me to capture the version for logging: repository contains all the code. This nginx conf file shows enabling http2, and forwarding the version.

What is HTTP/2


Google history A brief history of HTTP/2.

Who Uses HTTP/2 on the server?

As of September 2021, 46.2% (after topping out at just over 50%) of the top 10 million websites supported HTTP/2.

To check http version information I used curl:

# -I fetch headers only
# -L location ie will redo if a redirect
curl -I -L

# response
HTTP/2 200 # HERE - it is HTTP/2
cache-control: public, max-age=0, must-revalidate
content-type: text/html; charset=UTF-8
date: Thu, 07 Oct 2021 08:13:51 GMT
etag: "6f707a64bc1db898a2893600ff205662-ssl"
strict-transport-security: max-age=31536000; includeSubDomains; preload
server: Netlify
age: 0
x-nf-request-id: 01FHCX1P4S3GNPSCHD72RVQGC8

# To force a 1.1 connection use
curl -I -v --http1.1

Clients using HTTP/2

I can see from my Cloudflare stats (which sits in front of

alt text

Logging what is the request HTTP version

From nginx a way to pass the http version is to pass to kestrel as a request header:

# in nginx.conf
# the request variable ends with HTTP/1.0 HTTP/1.1 or HTTP/2
proxy_set_header X-DM-Request $request; 

Then in middleware in the Configure method:

var xDMRequest = context.Request.Headers.FirstOrDefault(x => x.Key == "X-DM-Request").Value;
string httpVersion = "none";
if (xDMRequest != StringValues.Empty)
    // get final HTTP/1.0 or 1.1 or 2
    var bar = xDMRequest.ToString().Split(new[] { "HTTP" }, StringSplitOptions.None).Last();
    httpVersion = $"HTTP{bar}";

Which gives the HttpVersion column in:

alt text

The custom logging in osr4rightstools which is used for dashboards and reporting.

Kestrel and Nginx

From reading the article above, I can see no real benefit running HTTP/2 on Kestrel, especially as nginx and Kestrel are on the same physical server.

I did get Kestrel running 2 as HTTP/2 is enabled by default in Kestrel

Enabling HTTP/2 in Kestrel over plain HTTP

In appsettings.json

  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
  "AllowedHosts": "*"

Be wary of spikes - a good warning of performance issues.


HTTP/2 has made little difference to my sites. But it is a ‘good thing’ to keep up to date.

I think :-)