Nginx Proxy Buffering Explained: proxy_request_buffering vs proxy_buffering Internals


1 views

In Nginx's proxy module, both directives control buffering but operate at different stages of the request-response cycle:

# Request flow diagram
client → Nginx (proxy_request_buffering) → upstream
client ← Nginx (proxy_buffering) ← upstream

When enabled (default: on), this buffers the entire client request body before forwarding to upstream servers. The internal workflow:

location /upload {
    proxy_request_buffering on;
    proxy_pass http://backend;
    client_max_body_size 10m;
    # Buffers to temporary files when exceeding memory limits
    client_body_buffer_size 128k;
}

Key characteristics:
- Uses memory buffers (client_body_buffer_size) initially
- Spills over to disk when memory buffer exhausted
- Enables proper Content-Length header generation
- Required for request body rewriting

Controls response buffering from upstream (default: on):

location /api {
    proxy_buffering on;
    proxy_buffers 8 4k;
    proxy_buffer_size 4k;
    proxy_busy_buffers_size 8k;
    proxy_max_temp_file_size 1024m;
    proxy_pass http://backend;
}

Critical aspects:
- Buffers response before sending to client
- Enables connection reuse to upstream
- Allows gzip compression of responses
- Improves performance for slow clients

Feature proxy_request_buffering proxy_buffering
Direction Client → Upstream Upstream → Client
Memory Buffer client_body_buffer_size proxy_buffer_size
Disk Spill client_body_in_file_only proxy_max_temp_file_size
Default on on

Disabling request buffering (useful for large uploads):

location /stream-upload {
    proxy_request_buffering off;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_pass http://backend;
}

Disabling response buffering (real-time streams):

location /live {
    proxy_buffering off;
    proxy_cache off;
    proxy_pass http://stream_backend;
}

Case 1: 502 errors with large file uploads

# Solution:
proxy_request_buffering on;
client_max_body_size 100m;
client_body_buffer_size 1m;
client_body_temp_path /tmp/nginx_upload 1 2;

Case 2: High memory usage with streaming responses

# Solution:
proxy_buffering off;
proxy_buffer_size 16k; # Minimal buffer for headers

In Nginx proxy configurations, both proxy_request_buffering and proxy_buffering deal with buffering - but at opposite ends of the request/response cycle:

# Request flow diagram:
Client → [proxy_request_buffering] → Nginx → Backend
# Response flow diagram:
Backend → [proxy_buffering] → Nginx → Client

This directive controls whether Nginx buffers the entire client request body before sending it to the proxied server. When enabled (default):

  • Nginx stores request body in memory (or disk if exceeding client_body_buffer_size)
  • Only forwards complete request after receiving all data
  • Uses 8K or 16K buffers (platform dependent) for reading
location /upload {
    proxy_request_buffering on;
    client_body_buffer_size 1m;
    client_max_body_size 10m;
}

This controls whether Nginx buffers responses from the proxied server:

  • Enabled by default with buffer size defined by proxy_buffer_size
  • Uses memory-based ring buffer architecture
  • When disabled, Nginx immediately passes each response chunk to client
location /stream {
    proxy_buffering off;
    proxy_pass http://backend;
}

Memory vs Latency Tradeoff:

Directive Memory Usage Latency Impact
proxy_request_buffering on Higher Delays request forwarding
proxy_buffering off Lower Reduces time-to-first-byte

For large file uploads with immediate processing:

location /big-upload {
    proxy_request_buffering off;
    proxy_buffering on;
    proxy_buffer_size 4k;
    proxy_buffers 8 4k;
    proxy_busy_buffers_size 8k;
    proxy_pass http://file_processor;
}

Key log settings for troubleshooting:

error_log /var/log/nginx/buffer_debug.log debug;
# Monitor buffer allocation:
log_format buffering '$remote_addr - $request_length/$bytes_sent '
                     '[$proxy_request_buffering/$proxy_buffering]';
access_log /var/log/nginx/buffer_access.log buffering;