Project

General

Profile

Actions

Docs ResourceTuning » History » Revision 3

« Previous | Revision 3/4 (diff) | Next »
gstrauss, 2021-08-29 20:26


Resource Tuning

Streaming

lighttpd provides multiple options to control streaming of the request body and the response body.

Streaming options affect how request and response bodies are buffered by lighttpd when the request is handled by a dynamic backend (mod_proxy, mod_fastcgi, mod_scgi, etc). lighttpd modules serving dynamic backends trigger reading of the request body, if any, when the lighttpd module is ready to handle the request body. If the lighttpd module handling the request is not interested in the request body, then the request body is not read before the request is handled and a response is sent. Similarly, when lighttpd sends a static file as a response, the request body (if any) is not read while lighttpd sends the static file response.

Keep in mind that lighttpd sends responses as quickly as the network allows, unless limited by Traffic Shaping.

Streaming settings affect dynamic handlers, but have no effect on static files:
server.stream-request-body
server.stream-response-body

By default, streaming of request body and streaming of response body are disabled: server.stream-request-body = 0 and server.stream-response-body = 0. With these settings, lighttpd efficiently offloads the request and response from the backend. lighttpd does not connect to the backend (or start the CGI program) until after the request body has been read and buffered in full by lighttpd. lighttpd reads and buffers the response from the backend as quickly as possible, and does not begin to send the response until after the response body has been read and buffered in full by lighttpd. For requests and responses over a certain size, lighttpd uses temporary files on disk to store the request and response bodies, limiting memory use. The result is that CPU- and memory-hungry backend processes run for as short a time as possible, and do not hang around taking up CPU and memory while waiting for the client to send or receive data over the network (which might be slow and lossy). An example: if the first thing that a CGI program does is to read the entire request body, then server.stream-request-body = 0 is recommended so that the CGI does not run longer than needed while waiting for the request body to arrive. If disk space for temporary files is very limited, then server.stream-request-body = 2 might be a better choice.

Non-zero values for server.stream-request-body or server.stream-response-body enable streaming in one or both directions, and in turn reduce lighttpd offloading in one or both directions. Enabling streaming reduces the latency before the backend starts receiving the request body, or before the client starts receiving the response body. This is desirable when the backend might send a response and abort reading the request body before the request body has finished uploading, or when the response produced by the backend is large, or takes a long time, or is produced in segments separated by time. FYI: any backend which supports Upgrade: websocket (e.g. mod_cgi cgi.upgrade = "enable" or mod_proxy proxy.header = ("upgrade" => "enable")) automatically enables streaming when the client connection is upgraded to use WebSockets.

If enabling streaming, consider whether or not to also adjust lighttpd default read and write timeouts:
server.max-read-idle - max number of seconds (default: 60) to wait to read new data from client, else close connection
server.max-write-idle - max number of seconds (default: 360) to wait to write pending data to client, else close connection
(added in lighttpd 1.4.60+:)
backend options *.server += ("write-timeout" => 0, "read-timeout" => 0) (default: no timeout to read/write from backend)
mod_cgi cgi.limits = ("write-timeout" => 0, "read-timeout" => 0) (default: no timeout to read/write from CGI)

With server.stream-request-body = 1 or server.stream-response-body = 1, lighttpd continues to read as quickly as the network allows from client or from backend, buffering large bodies into temporary files on disk. If disk space is limited, then server.stream-request-body = 2 or server.stream-response-body = 2 will limit lighttpd use of temporary files to emptying kernel socket or pipe buffers, and will pause reading additional data from client until lighttpd has written more data to the backend, or will pause reading additional data from the backend until lighttpd has written more data to the client. This may introduce latency in the request/response, but is also much less likely to fill up limited disk space if disk space is one of the primary resource constraints.

server.upload-dirs is used to configure the locations where lighttpd stores temporary files. The configured locations are used for both request bodies and response bodies, despite containing the word "upload". server.upload-dirs is a list and may contain more than one directory. If the first location fills up, then lighttpd will retry writing additional temporary files to the next location in the list. Using multiple directories is useful in cases where most temporary files will fit in fast in-memory filesystems (of limited size), e.g. /dev/shm, and it is desirable to reduce writes to /usr/local/tmp on flash memory on embedded system: server.upload-dirs = ( "/dev/shm", "/usr/local/tmp" ). The default is server.upload-dirs = ("/var/tmp"), as /var/tmp is often larger than /tmp. However, on embedded systems, /var/tmp might symlink to /tmp, and /tmp might be an in-memory filesystem of limited size, in which case server.stream-request-body = 2 might be a good choice.

When creating temporary files, lighttpd limits the size of each file to about 1 MB (fuzzy) per file by default, and this is configurable with server.upload-temp-file-size (in bytes). The reason for using multiple temporary files of a (relatively) small size is so that each temporary file can be removed (and the space freed) as soon as that one file is read by the backend, or sent to the client. This is intentional to avoid storing the entire result (in either direction) and taking up a growing amount of disk space for the entire length of time for the request or response. If server.stream-request-body = 0 (the default), disk space is limited, and the first thing that a CGI does is to read the entire request body into another temporary file, then with lighttpd 1.4.60 and later, server.feature-flags += ("cgi.tempfile-accum" => "disable") is also recommended to disable an optimization in mod_cgi.

Some additional related options:
server.max-connections - maximum number of client connections to handled at one time
server.max-request-field-size - maximum size in bytes of the request header (default 8192 (8k); max configurable up to 64k-1)
server.max-request-size - maximum size in kbytes of the request (header + body) (default: 0 is no limit)

Updated by gstrauss over 2 years ago · 3 revisions