20

I see that proxy_request_buffering will buffer the request and proxy_buffering the response.

However I would like to understand the internals of what this means.

1 Answer 1

20

From Nginx documention:

Proxy_Buffering

Syntax: proxy_buffering on | off;
Default:    
proxy_buffering on;
Context:    http, server, location
Enables or disables buffering of responses from the proxied server.

When buffering is enabled, nginx receives a response from the proxied server as soon as possible, saving it into the buffers set by the proxy_buffer_size and proxy_buffers directives. If the whole response does not fit into memory, a part of it can be saved to a temporary file on the disk. Writing to temporary files is controlled by the proxy_max_temp_file_size and proxy_temp_file_write_size directives.

When buffering is disabled, the response is passed to a client synchronously, immediately as it is received. nginx will not try to read the whole response from the proxied server. The maximum size of the data that nginx can receive from the server at a time is set by the proxy_buffer_size directive.

Buffering can also be enabled or disabled by passing “yes” or “no” in the “X-Accel-Buffering” response header field. This capability can be disabled using the proxy_ignore_headers directive.

Proxy_Request_Buffering

Syntax: proxy_request_buffering on | off;
Default:    
proxy_request_buffering on;
Context:    http, server, location
This directive appeared in version 1.7.11.
Enables or disables buffering of a client request body.

When buffering is enabled, the entire request body is read from the client before sending the request to a proxied server.

When buffering is disabled, the request body is sent to the proxied server immediately as it is received. In this case, the request cannot be passed to the next server if nginx already started sending the request body.

When HTTP/1.1 chunked transfer encoding is used to send the original request body, the request body will be buffered regardless of the directive value unless HTTP/1.1 is enabled for proxying.

4
  • 3
    So if you're sending an 10GB file, nginx will buffer this before forwarding it? Doesn't that mean it introduces a lot of latency?
    – Sam
    Feb 1, 2023 at 9:40
  • @Sam Yes. If proxy_request_buffering on (the default), when the client sends (== uploads) 10GB, nginx will buffer the entire 10GB before sending anything to the upstream server. proxy_request_buffering on disables any streaming from nginx to the proxied upstream server. In the other direction (client <- nginx), nginx does not work that way: There nginx starts streaming pretty much immediately; it will not delay sending data to the client until e.g. the disk-based buffer proxy_max_temp_file_size (current default 1GB) is full. I just tested this with nginx 1.22.0 on Linux.
    – nh2
    Mar 19, 2023 at 13:25
  • @nh2 @bentek I noticed that after setting proxy_request_buffering off Nginx stops proxying the original Content-Length header and just removes it. What is the reason of such behaviour?
    – Nawa
    Apr 26, 2023 at 12:17
  • @Nawa I do not observe nginx 1.22 removing Content-Length from requests when proxying. I just tested it using this minimal nginx config with an added location / { proxy_pass "http://localhost:1235"; proxy_request_buffering off; } to strace -s 3000 python3 -m http.server --bind 127.0.0.1 1235 2>&1 | grep -i content-length. strace shows that if I e.g. curl 'http://localhost:1234/' -d 'hello', the upstream Python server correctly receives Content-Length: 5.
    – nh2
    Apr 28, 2023 at 12:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .