The warning message
"a client request body is buffered to a temporary file"
indicates Nginx's standard behavior when handling request bodies larger than the configuredclient_body_buffer_size
. While not an error, this reveals optimization opportunities.# In nginx.conf or your server block: client_body_buffer_size 100k; # Default is 8k or 16k depending on platform client_max_body_size 1000m; # Maximum allowed client request body size client_body_temp_path /var/lib/nginx/body 1 2; # Custom temp path configuration client_body_in_file_only clean; # Alternative approach for debugging
For production environments handling large uploads:
- Set
client_body_buffer_size
to match your typical request size (e.g., 1M for most API requests) - Keep
client_max_body_size
slightly larger than your maximum expected file size - Consider SSD storage for
client_body_temp_path
when handling frequent large uploads
Setting an extremely large buffer (like 1000M) consumes more memory per connection but reduces disk I/O. Benchmark different values:
# Test configuration with varying buffer sizes:
# Small buffer (frequent disk writes)
client_body_buffer_size 8k;
# Medium buffer (balanced approach)
client_body_buffer_size 1m;
# Large buffer (memory intensive)
client_body_buffer_size 100m;
Use these commands to verify your configuration:
nginx -T | grep client_body # Show active client body settings
ls -lh /var/lib/nginx/body # Check temp file usage
iotop -o # Monitor disk I/O during uploads
For specialized cases:
# Stream uploads directly to backend (bypass Nginx buffering)
location /upload {
proxy_request_buffering off;
proxy_pass http://backend;
}
# Use HTTP/2 for better large file transfer performance
listen 443 ssl http2;
When Nginx receives client requests with bodies (like file uploads), it handles them through a buffering mechanism. The client_body_buffer_size
directive determines when Nginx switches from memory buffering to disk buffering:
# Default configuration
client_body_buffer_size 8k|16k; # Depending on platform
The message "a client request body is buffered to a temporary file
" indicates the request body exceeded your buffer size setting and was written to disk at /var/lib/nginx/body/
.
For production systems handling large uploads:
http {
# Set buffer size to match your average upload size
client_body_buffer_size 10m;
# Configure temporary storage path
client_body_temp_path /var/nginx/client_body 1 2;
# Maximum allowed size for client request body
client_max_body_size 100m;
}
Key considerations when setting these values:
- Memory vs. Disk Tradeoff: Larger buffers consume more RAM but reduce disk I/O
- Concurrent Connections: Total buffer memory = buffer_size × concurrent connections
- Security: Always set
client_max_body_size
to prevent DOS attacks
Here's how to test different configurations with Apache Bench:
# Test with 100MB file upload
ab -n 50 -c 5 -p large_file.bin -T 'multipart/form-data; boundary=12345' \
http://yourserver.com/upload
Monitor disk I/O during tests:
iostat -x 1 # Look for %util on the disk containing temp files
vmstat 1 # Check si/so fields for swapping
For high-performance upload servers:
client_body_in_file_only clean;
client_body_buffer_size 1m;
client_body_in_single_buffer on;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
output_buffers 1 1m;
sendfile_max_chunk 512k;
Consider these additional optimizations:
- Use separate storage devices for temp files
- Adjust filesystem mount options (noatime, nobarrier)
- Increase worker_connections if handling many parallel uploads
For AWS EC2 instances:
# Use instance storage for temp files if available
client_body_temp_path /mnt/ephemeral/nginx_body;
For Kubernetes deployments:
# Use emptyDir volume with size limit
volumeMounts:
- name: nginx-temp
mountPath: /var/lib/nginx/body
readOnly: false