1================== 2Performance Tuning 3================== 4 5[[ Note: latest version is found at https://wiki.lighttpd.net/Docs_Performance ]] 6[[ Note: see version with links at https://wiki.lighttpd.net/Docs_Performance ]] 7 8important performance tuning rules 9 10* Prefer lighttpd defaults unless you have a reason to change a setting, 11 and unless you test that changing the setting is beneficial to you. 12* Proper functionality is more important than marginal increases in performance; 13 a web server that does not function as intended is not useful. 14 Do not sacrifice security or desired operational functioning for marginal 15 performance improvements. 16* Performance tuning is not magic. The recommended approach is that one change 17 be made at a time, that the change be tested and benchmarked, and that if the 18 change does not have a measurable and positive impact in real-world scenarios, 19 that the change be reverted. 20 21lighttpd is generally pretty snappy. 22Most of the following are micro-optimizations. 23No changes are required unless you have a specific performance issue that you 24must address. 25 26 27lighttpd configuration performance tuning (technical guidelines) 28----------------------------------------- 29 30* less is more (and is often simpler, too) 31 - rely on defaults where possible to reduce unnecessary (duplicative) config 32 processing (at runtime) to process configuration directives which were 33 already set to the default values 34 - set config options in the global scope rather than repeating in sub-scopes. 35 lighttpd optimizes configuration settings in the global scope and makes 36 those settings the defaults 37 - TLS configuration can be set in the global scope and inherited by multiple 38 $SERVER["socket"] 39 ssl.pemfile = "..." 40 ssl.privkey = "..." 41 $SERVER["socket"] == ":443" { ssl.engine = "enable" } 42 $SERVER["socket"] == "[::]:443" { ssl.engine = "enable" } 43 - list only the modules actually used and enabled in server.modules; 44 comment out the others 45 - each loaded module registers itself into lighttpd hooks and gets a chance 46 to handle each request, which is is unnecessary if a module is loaded but 47 not otherwise configured to be used 48 - server.compat-module-load = "disable" skips loading the default modules 49 (mod_indexfile, mod_dirlisting, mod_staticfile), and you can then 50 explicitly add one or more to server.modules to use them 51 - tweaks to remove optional functionality 52 - server.tag = "" skips sending "Server: lighttpd/1.4.xx" in responses; 53 alternatively, use: server.tag = "lighttpd" to hide the lighttpd version 54 - server.range-requests = "disable" can be used if all server responses are 55 small files, but otherwise it is recommended to be left enabled 56 - review the default lighttpd config provided by your distro 57 - configs provided by distros aim to be newbie friendly but can introduce 58 complexity of yet another config framework 59 - configs provided by distros are often out-dated and then kept for historic 60 compatibility, rather than current best practices 61 - example: ~20 years ago some widely used versions of Adobe Acrobat reader 62 plugin PDF clients misbehaved with range requests. Unfortunately, the 63 config setting to disable range requests for PDFs has been cargo-culted 64 into configs since then. Prefer to comment out or remove: 65 $HTTP["url"] =~ "\.pdf$" { server.range-requests = "disable" } 66 - server.max-connections limits the maximum number of simultaneous connections 67 to handle and also affects memory usage for the connection cache 68 - default is (about) 1365 which is oversized for all but the largest 69 systems. Embedded systems might set server.max-connections = 16 or lower 70 - server.max-worker = 0 should generally be left unset (or "0"), as 71 CPU bottlenecks are usually elsewhere 72 - server.follow-symlink = "enable" (default) should be left enabled. If such 73 restrictions are required, prefer to run a separate lighttp instance under a 74 separate user account, and enforce more restrictive file access permissions. 75 - ssl.read-ahead = "disable" (default) is strongly recommended for slower, 76 embedded systems which process TLS packets more slowly than network 77 wire-speed. For faster systems, test if ssl.read-ahead = "enable" improves 78 performance (or not) 79 - prefer to configure mod_extforward extforward.hap-PROXY for lighttpd 80 instances behind HAProxy or load balancers supporting the HAProxy PROXY 81 protocol 82* minimize conditional processing (but not at the cost of proper functionality) 83 - more conditions means more config processing at runtime 84 - more conditions means more memory used by config per request 85 - avoid repeating conditions and its opposite by joining them into if/else 86 <condition> { ... } else { ... } 87 <condition> { ... } else <condition> { ... } else { ... } 88 - sometimes it may take fewer config lines to set a config option once in the 89 global scope and then, where necessary, to unset the option in a small 90 number of conditions rather than leaving the default in the global scope 91 and enabling the config option in many more conditions 92 - having no config conditions will be among the fastest configs to be 93 processed, but config processing at runtime is fast and is not typically 94 a bottleneck 95* dynamic backends (mod_proxy, mod_fastcgi, mod_scgi, mod_ajp13, ...) 96 - prefer to use unix domain sockets (instead of TCP sockets) for connections 97 from lighttpd to backends running on the same host 98 - lighttpd can listen on a unix domain socket 99 (server.bind = "/path/to/lighttpd.sock") 100 and lighttpd mod_proxy can act as a reverse-proxy to a backend lighttpd 101 server. Use with mod_extforward to preserve client remote address for the 102 backend. 103* mod_fastcgi 104 - Recommended: use PHP-FPM (FastCGI Process Manager), 105 which is available as a package in many OS distros 106 - If not using PHP-FPM, then see Docs_PerformanceFastCGI 107 - lighttpd provides mechanisms for lighttpd to start up PHP backends, and 108 that works well, but PHP-FPM is the modern and recommended mechanism to 109 manage PHP backends 110* mod_rewrite and mod_redirect: short-circuiting 111 (when using a sequence of regexes) 112 - consider putting static file matches (passed through unmodified) first, 113 and using a blank target to indicate no modification 114 - consider using a blank match as a catch-all, rather than "^(.*)", 115 which will still match all, but without the regex 116 url.rewrite-once = ( 117 "^/static/|\.(?:css|jpg)$" => "", 118 "" => "/index.php${url.path}${qsa}" 119 ) 120* mod_indexfile: reduce the number of entries in index-file.names, 121 if mod_indexfile is enabled 122 - index-file.names = ("index.html") as a list of one or two entries rather 123 than a list of, say, 10 differenent file extensions 124* cache tuning 125 - stat_cache: default server.stat_cache-engine = "simple" works well for 126 typical usage and caches stat() results for 1-2 seconds. Test with 127 server.stat-cache-engine = "inotify" or server.stat-cache-engine = "kqueue" 128 for stat() results to be cached longer (16 seconds) 129 - mod_auth: set auth.cache = ("max-age" => "600") to cache passwords (default 130 disabled), but acknowledge changes to your security posture if enabling the 131 cache. (since lighttpd 1.4.56) 132 - mod_deflate: set deflate.cache-dir to cache (and reuse) compressed static 133 assets based on ETag (since lighttpd 1.4.56) 134 - mod_dirlisting: set dir-listing.cache = ( ... ) to configure caching of 135 generated directory listings (since lighttpd 1.4.60) 136* do not sacrifice security to save a few CPU cycles 137 - server.http-parseopts* option defaults are recommended, and are very fast 138 - disabling server.http-parseopts* might save a few CPU cycles, but is an 139 anti-pattern for secure configurations 140 - server.http-parseopts* options should be modified only when the 141 functionality needs to be tuned for proper site operation 142 - ETag response headers are used in HTTP/1.1 conditional caching. 143 ETag response headers are also required for mod_deflate and strongly 144 recommended with mod_webdav. While lighttpd ETag generation for 145 static content can be disabled for micro-benchmarking purposes, 146 ETag generation (default enabled) is recommended for production use 147 (etag.use-inode, etag.use-mtime, etag.use-size) 148* compile lighttpd with mmap support (./configure --enable-mmap) to improve 149 mod_deflate performance 150 151 152lighttpd configuration for use of operating system (OS) features 153---------------------------------------------------------------- 154 155lighttpd generally chooses optimal defaults for the OS on which it is running. 156Prefer lighttpd defaults unless something is not functioning correctly. 157(Please report bugs and include your platform information if the lighttpd OS 158 defaults are not working correctly.) 159 160* server.event-handler (e.g. epoll, kqueue, event ports, devpoll, poll, ...) 161* server.network-backend (e.g. sendfile, writev, write) 162 163 164lighttpd configuration tuning for high-traffic sites with a large number of connections 165--------------------------------------------------------------------------------------- 166 167* test with server.max-fds = 16384 (or higher) and OS system and/or per-user 168 ulimit -Hn might need to be adjusted to allow this or higher values. 169 For each 4k increase in server.max-fds, lighttpd uses an additional ~100 kb 170 of memory for internal structures, not including memory used by each active 171 connection. (In other words, there is a marginal cost for using very high 172 values when there are not nearly so many simultaneous open connections). 173 server.max-connections is calculated to be 1/3 of server.max-fds if 174 server.max-connections is not configured. 175 176 177lighttpd configuration tuning for low-memory systems 178---------------------------------------------------- 179 180* test with server.max-fds = 128 (or lower) 181* test with server.max-connections = 16 (or lower) 182* test with server.listen-backlog = 16 (or lower) 183* (default) server.stat_cache-engine = "simple" 184* (default) ssl.read-ahead = "disable" 185* support for the HTTP/2 protocol (enabled by default in lighttpd 1.4.59) uses 186 more memory than HTTP/1.1; low-memory systems might choose to disable HTTP/2 187 protocol support: server.feature-flags += ("server.h2proto" => "disable") 188 189 190lighttpd configuration tuning for traffic shapping (download rate-limiting) 191-------------------------------------------------- 192 193connection.kbytes-per-second 194server.kbytes-per-second 195 196 197lighttpd configuration tuning for timeouts 198------------------------------------------ 199 200To free up connections more quickly, tune down the idle timeouts for how long 201lighttpd waits to read or write to the client (when lighttpd is trying to read 202or write), or how long lighttpd waits for the next keep-alive request, and for 203how many keep-alive requests, before lighttpd closes the connection. A value 204of 0 disables an idle timeout and is not recommended. 205* server.max-read-idle = 60 206* server.max-write-idle = 360 207* server.max-keep-alive-idle = 5 208* server.max-keep-alive-requests = 100 209Generally, server.max-keep-alive-requests should not be set to 0 since setting 210up a new TCP connection takes more resources than keeping an open idle fd, 211especially if the connection is over TLS. 212 213 214Platform-Specific Notes 215======================= 216 217Note: The following is old and possibly out-dated. 218 Please consider only as a starting point for further testing. 219 220Linux 221----- 222 223For Linux 2.4.x you should think about compiling lighttpd with the option 224``--disable-lfs`` to disable the support for files larger than 2GB. lighttpd will 225fall back to the ``writev() + mmap()`` network calls which is ok, but not as 226fast as possible but support files larger than 2GB. 227 228Disabling the TCP options reduces the overhead of each TCP packet and might 229help to get the last few percent of performance out of the server. Be aware that 230disabling these options most likely decreases performance for high-latency and lossy 231links. 232 233- net.ipv4.tcp_sack = 0 234- net.ipv4.tcp_timestamps = 0 235 236Increasing the TCP send and receive buffers will increase the performance a 237lot if (and only if) you have a lot of large files to send. 238 239- net.ipv4.tcp_wmem = 4096 65536 524288 240- net.core.wmem_max = 1048576 241 242If you have a lot of large file uploads, increasing the receive buffers will help. 243 244- net.ipv4.tcp_rmem = 4096 87380 524288 245- net.core.rmem_max = 1048576 246 247Keep in mind that every TCP connection uses the configured amount of memory for socket 248buffers. If you've got many connections this can quickly drain the available memory. 249 250See http://www.acc.umu.se/~maswan/linux-netperf.txt for more information on these parameters. 251 252FreeBSD 253------- 254 255On FreeBSD you might gain some performance by enabling accept filters. Just 256compile your kernel with: :: 257 258 options ACCEPT_FILTER_HTTP 259 260For more ideas about tuning FreeBSD read: tuning(7) 261 262Reducing the recvspace should always be ok if the server only handles HTTP 263requests without large uploads. Increasing the sendspace would reduce the 264system load if you have a lot of large files to be sent, but keep in mind that 265you have to provide the memory in the kernel for each connection. 1024 * 64KB 266would mean 64MB of kernel RAM. Keep this in mind. 267 268- net.inet.tcp.recvspace = 4096 269 270