This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NB configs in this Markdown may not be current. The included files are up-to-date.
Introduction
By default when Nginx starts receiving a response from a FastCGI backend (such as PHP-FPM) it will buffer the response in memory before delivering it to the client. Any response larger than the set buffer size is saved to a temporary file on disk.
Since disk is slow and memory is fast the aim is to get as many FastCGI responses passing only through memory. On the flip side we don't want to set an excessively large buffer as they are created and sized on a per request basis - it's not shared.
The related Nginx options are:
fastcgi_buffering first appeared in Nginx 1.5.6 (1.6.0 stable) and can be used to turn buffering completely on/off. It's on by default.
fastcgi_buffer_size is a special buffer space used to hold the first chunk of the FastCGI response, which is going to be the HTTP response headers.
You shouldn't need to adjust this from the default - even if Nginx defaults to the smallest page size of 4KB (your platform will determine if 4/8k buffer) it should fit your typical HTTP header.
One exception is frameworks that push large amounts of cookie data via the Set-Cookie HTTP header during their user verification/login phase - blowing out the buffer and resulting in a HTTP 500 error. In those instances you will need to increase this buffer to 8k/16k/32k to fully accommodate your largest upstream HTTP header being pushed.
fastcgi_buffers controls the number and memory size of buffer segments used for the payload of the FastCGI response.
Most, if not all of our tweaking will be based on the fastcgi_buffers directive for the remainder of this guide.
Determine actual FastCGI response sizes
By processing our Nginx access logs we can determine both maximum and average response sizes. The basis of this awk recipe was found here.
awk '($10~/200/) {i++;sum+=$11;max=$11>max?$11:max;} END {printf("Maximum=%d\nAverage=%d\n",max,i?sum/i:0);}' access.log
Maximum: 575458
Average: 10215
Creating a filtered access.log for FastCGI
Note: this recipe are going to report on all access requests returning an HTTP 200 code, you might want to filter FastCGI requests into a separate Nginx access logfile for reporting. For example, for PHP-FPM:
location ~ \.php$ {
include /etc/nginx/snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
# Not required permanently. Output FastCGI requests to it's own Nginx log fileaccess_log /var/log/nginx/phpfpmonly-access.log;
}
Process the access requests from the newly configured php-fpm-access.log:
awk '($10~/200/) {i++;sum+=$11;max=$11>max?$11:max;} END {printf("Maximum=%d\nAverage=%d\n",max,i?sum/i:0);}' phpfpm-access.log
Maximum: 569990
Average: 11820
Default memory pagesize
The default memory pagesize (in bytes) for an operating system can be determined by the following command:
$ getconf PAGESIZE
4096
With these values in hand we are now much better equipped to set fastcgi_buffers.
Setting the buffer size
The fastcgi_buffers setting takes two values, buffer segment count and memory size, by default it will be:
fastcgi_buffers8 4k|8k;
So a total of 8 buffer segments at either 4k/8k, which is determined by the platform memory page size.
For Debian/Ubuntu Linux that turns out to be 4096 bytes (4K) - so a default total buffer size of 32KB.
Based on the maximum/average response sizes determined above we can now raise/lower these values to suit. Typically you would keep buffer size at the default value (memory pagesize) and adjust the buffer segment count to a value that keeps the bulk of responses handled by FastCGI loaded in buffer RAM.
If your response size averages are on the higher side, consider lowering the buffer segment count and increasing the memory size in pagesize multiples (8k/16k/32k).
Verifying our results
We can see how often FastCGI responses are being saved to disk by grepping our Nginx error log(s):
grep --extended-regexp "\[warn\].+buffered" error.log
# or the older gzipped files
zgrep --extended-regexp "\[warn\].+buffered" error.log.2.gz
# will return lines like:
YYYY/MM/DD HH:MM:SS [warn] 1234#0: *123456 an upstream response is buffered to a temporary file...
Remember it's not necessarily a bad situation to have some larger responses buffered to disk. Aim for a balance where only a small portion of your largest responses are handled in this way.
Warning: Do NOT try to stuff all your fastcgi_buffers responses into memory
WARNING: The practice of ramping up fastcgi_buffers to an excessive number and/or size value in an attempt to fit all FastCGI responses purely in RAM is something Peter and Virgil would strongly recommend against.
Unless your Nginx server is only receiving a few concurrent requests at any one time, you risk exhausting available system memory.
Updated config snippet
# Setting Nginx FastCGI response buffer sizes# http://bit.ly/nginx_fastcgi_bufferslocation ~ \.php$ {
include /etc/nginx/snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_buffers1284k; # Modified count at default size.# Do NOT change buffer_size. See Gist. # Current $fastcgi_buffers directive ..# fastcgi_buffer_size 4k; # ... sets this to 512kfastcgi_busy_buffers_size 8k; # default=2 x buffersfastcgi_max_temp_file_size1024m; # written in **$fastcgi_temp_file_write_size** chunksfastcgi_temp_file_write_size 32k; # default=2 x buffers# TODO: New directives to research# fastcgi_read_timeout 600;# fastcgi_send_timeout 600;# Not required permanently. Output just FastCGI requests to it's own Nginx log file.# access_log /var/log/nginx/phpfpm-access.log;
}
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Changelog
Access-Control-Allow-Headers
in mauticdemo-nginx.confPHP-FPM
config stanza.zgrep
examplecat error.log |
from the Verifying section commandsawk
columns from$9 $10
to$10 $11
as ourlog_format
prepends a$host:
columnnginx.conf
config file example with @virgilwashere real world example