When working with media streaming applications like Madsonic behind Nginx, buffered uploads can cause significant problems:
- Progress bars fail to update in real-time
- Temporary files create unnecessary disk I/O
- Memory usage spikes with large uploads
- 31115#0 client request body warnings appear in logs
Here's the optimized configuration that completely disables all request buffering:
location / {
proxy_pass https://madsonic-server/;
# Critical buffering directives
proxy_buffering off;
proxy_request_buffering off;
client_body_in_file_only off;
# Buffer size adjustments
client_body_buffer_size 0;
client_max_body_size 0;
proxy_max_temp_file_size 0;
# Timeout extensions for large uploads
proxy_read_timeout 18000;
proxy_send_timeout 18000;
client_body_timeout 18000;
# HTTP protocol optimizations
proxy_http_version 1.1;
proxy_set_header Connection "";
# Standard proxy headers
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Understand these critical aspects of the solution:
Directive | Purpose | Impact |
---|---|---|
proxy_request_buffering | Disables initial request buffering | Eliminates 31115 warnings |
client_body_buffer_size 0 | Prevents memory buffering | Forces direct streaming |
proxy_max_temp_file_size 0 | Blocks disk buffering | Reduces I/O overhead |
Verify the solution works with these methods:
- Progress monitoring: Upload a large file (1GB+) and check if progress updates smoothly
- Log verification: Search Nginx error logs for "a client request body is buffered" messages
- Real-time testing: Use
ngrep
to monitor packet flow during uploads:ngrep -d any port 443 and host your-madsonic-server
For production environments handling heavy upload traffic:
# Kernel-level optimizations
net.ipv4.tcp_tw_reuse = 1
net.core.somaxconn = 1024
net.ipv4.tcp_fin_timeout = 30
# Nginx worker adjustments
worker_processes auto;
worker_rlimit_nofile 100000;
events {
worker_connections 4000;
multi_accept on;
use epoll;
}
Watch out for these issues:
- Firewalls interrupting long-running connections
- Corporate proxies injecting buffering
- SSL termination points adding their own buffering
- Client-side JavaScript upload libraries with their own chunking
When setting up reverse proxies with Nginx, many developers encounter the frustrating a client request body is buffered to a temporary file
warning. This occurs particularly during file uploads through web interfaces like Madsonic, where progress indicators fail due to buffering behavior.
By default, Nginx buffers client request bodies when:
- The body size exceeds
client_body_buffer_size
- The request needs to be passed to a backend server
- The client connection speed is slower than backend processing
This buffer-and-forward approach helps with performance in most cases but becomes problematic for real-time upload scenarios.
Here's the definitive configuration to eliminate all request buffering:
location / {
proxy_pass https://madsonic-server/;
proxy_redirect off;
# Critical buffering controls
proxy_buffering off;
proxy_request_buffering off;
client_body_in_file_only clean;
client_body_buffer_size 0;
# Connection tuning
proxy_http_version 1.1;
proxy_read_timeout 18000;
proxy_send_timeout 18000;
# Headers for proper backend handling
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
1. proxy_request_buffering off
This is the primary directive that disables buffering of client request bodies. When off, Nginx immediately begins sending data to the backend.
2. client_body_in_file_only clean
Forces Nginx to write request bodies directly to disk without buffering, then immediately deletes the files after processing.
3. client_body_buffer_size 0
Eliminates memory buffering completely by setting the buffer size to zero.
While this configuration solves the upload progress issue, be aware that:
- Backend servers must handle slow clients directly
- No protection against slow client attacks
- May increase backend server load
For production environments with untrusted clients, consider implementing rate limiting separately:
limit_req_zone $binary_remote_addr zone=upload:10m rate=1r/s;
location /upload {
limit_req zone=upload burst=5;
# Include the bufferless config above
}
If you still see buffering occurring:
- Check for multiple location blocks matching your URL
- Verify Nginx version supports these directives (1.7.11+)
- Inspect both HTTP and server-level configuration
- Test with
curl -v -T largefile.ext http://yourserver
Remember that some modules (like upload modules) may implement their own buffering regardless of these settings.