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;