47

I use nginx as a reverse-ssl-proxy in front of a backend webserver that is capable of doing HTTP/2.0.

I noticed that nginx proxies the requests to the backend server via HTTP/1.1 rather than HTTP/2.0. Is it possible to tell nginx to use an un-encrypted HTTP/2.0 connection instead? Would this increase performance?

gxx
  • 5,591
  • 2
  • 22
  • 42
S1lentSt0rm
  • 1,039
  • 1
  • 9
  • 11
  • although http2 specs say that it doesn't require encryption, nginx currently doesn't support http2 without ssl. – Marco Mar 22 '16 at 10:50
  • So it would use HTTP/2.0 if I had specified a https:// address? Well, then I guess I'm better of using HTTP/1.1. It doesn't make sense to encrypt the traffic twice and the performance of HTTP/2.0 with ssl would probably not be as good as HTTP/1.1 without ssl, would it? I mean, that kind of makes the reverse-ssl-proxy useless ;) – S1lentSt0rm Mar 22 '16 at 11:09
  • It doesn't really matter if you encrypt the traffic between front and backend server if they are on the same machine. as for performance: http2 ist quite a bit faster than http1.1, even with encryption. can't say without trying if it would make a difference. – Marco Mar 22 '16 at 11:14
  • 1
    https://www.nginx.com/blog/nginx-1-13-9-http2-server-push – malix Apr 18 '18 at 18:55
  • Crossed this thread when debugging nginx 504 timeouts. – Mike Ciffone Feb 06 '22 at 00:31

3 Answers3

34

Found this: https://trac.nginx.org/nginx/ticket/923

There are no plans to implement HTTP/2 support in the proxy module in the foreseeable future

Excerpt from a mail referenced in the ticket:

There is almost no sense to implement it, as the main HTTP/2 benefit is that it allows multiplexing many requests within a single connection, thus [almost] removing the limit on number of simalteneous requests - and there is no such limit when talking to your own backends. Moreover, things may even become worse when using HTTP/2 to backends, due to single TCP connection being used instead of multiple ones.

S1lentSt0rm
  • 1,039
  • 1
  • 9
  • 11
  • 11
    It looks like this means you can't use HTTP/2 Server Push if you are proxying with nginx, even if the backend server would otherwise support it if it was accessed directly. – thomasrutter Mar 21 '17 at 00:38
  • 10
    I use nginx reverse proxies for non-local sites over slow connections so HTTP/2 would help me. It's a shame that the nginx developers haven't considered that use case :-(. – markshep Jan 22 '19 at 10:47
  • 1
    Now there seems to be a support for it https://www.nginx.com/blog/nginx-1-13-9-http2-server-push/ – Musa Haidari Sep 07 '22 at 14:37
  • I am currently reading HTTP/2 protocol doc (RFC7540), still don't understand how it becomes worse when there is only one TCP connection multiplexing requests between Nginx and your backend app server. Is it because all the requests (from different clients) will be crammed into the single TCP connection thus leads to performance reduction ? – Ham Feb 10 '23 at 05:07
11

Sadly nginx not support proxy to a http/2 backend server, referenced from https://www.nginx.com/blog/http2-module-nginx/#QandA

Q: Will you support HTTP/2 on the upstream side as well, or only support HTTP/2 on the client side?

A: At the moment, we only support HTTP/2 on the client side. You can’t configure HTTP/2 with proxy_pass. [Editor – In the original version of this post, this sentence was incorrectly transcribed as “You can configure HTTP/2 with proxy_pass.” We apologize for any confusion this may have caused.]

But what is the point of HTTP/2 on the backend side? Because as you can see from the benchmarks, there’s not much benefit in HTTP/2 for low‑latency networks such as upstream connections.

Also, in NGINX you have the keepalive module, and you can configure a keepalive cache. The main performance benefit of HTTP/2 is to eliminate additional handshakes, but if you do that already with a keepalive cache, you don’t need HTTP/2 on the upstream side.

tangxinfa
  • 211
  • 2
  • 4
5

As of version 1.13.9 http2 is supported for server pushes.

One way is to define a list of assets that you would like pushed back upon a request to a specific location using the http2_push statement.

A second way is to let nginx intercept the response and push the link tags with the preload attribute using the http2_push_preload statement.

More details in the blog post that @malix referenced in the comments of the OP

Aaron
  • 193
  • 2
  • 7
  • And is it simply a matter of adding `proxy_http_version 2;` ? – Pim van der Heijden Nov 23 '22 at 22:06
  • 1
    No. As of v1.22 (currently, the latest stable release), `proxy_http_version` still doesn't include `http/2` . See [detail implementation](https://github.com/nginx/nginx/blob/branches/stable-1.22/src/http/modules/ngx_http_proxy_module.c#L285) – Ham Feb 10 '23 at 05:17