WSGIDaemonProcess
- Description:
Configure a distinct daemon process for running applications.
- Syntax:
WSGIDaemonProcessname[options]- Context:
server config, virtual host
The WSGIDaemonProcess directive can be used to specify that distinct
daemon processes should be created to which the running of WSGI
applications can be delegated. Where Apache has been started as the
root user, the daemon processes can be run as a user different to that
which the Apache child processes would normally be run as.
When distinct daemon processes are enabled and used, the process is dedicated to mod_wsgi and the only thing that the processes do is run the WSGI applications assigned to that process group. Any other Apache modules such as PHP or activities such as serving up static files continue to be run in the standard Apache child processes.
Note that having denoted that daemon processes should be created by
using the WSGIDaemonProcess directive, the WSGIProcessGroup
directive, or the process-group option of WSGIScriptAlias still
needs to be used to delegate specific WSGI applications to execute within
those daemon processes.
Also note that the name of the daemon process group must be unique for the whole server. That is, it is not possible to use the same daemon process group name in different virtual hosts.
Options which can be supplied to the WSGIDaemonProcess directive are:
- processes=num
Defines the number of daemon processes that should be started in this process group. If not defined then only one process will be run in this process group.
Note that if this option is defined as
processes=1, then the WSGI environment attribute calledwsgi.multiprocesswill be set to beTruewhereas not providing the option at all will result in the attribute being set to beFalse. This distinction is to allow for where some form of load balancing is used across process groups in the same Apache instance, or separate Apache instances. If you need to ensure thatwsgi.multiprocessisFalseso that interactive debuggers will work, simply do not specify theprocessesoption and allow the default single daemon process to be created in the process group.
- threads=num
Defines the number of threads to be created to handle requests in each daemon process within the process group.
If this option is not defined then the default will be to create 15 threads in each daemon process within the process group.
Do not get carried away and set this to a very large number in the belief that it will somehow magically enable you to handle many more concurrent users. Any sort of increased value would only be appropriate where your code is I/O bound. If you code is CPU bound, you are better of using at most 3 to 5 threads per process and using more processes.
If you set the number of threads to 0 you will enable a special mode intended for using a daemon process to run a managed set of processes. You will need to use
WSGIImportScriptto pre-load a Python script into the main application group specified by%{GLOBAL}where the script runs a never ending task, or does an exec to run an external program. If the script or external program exits, the process is shutdown and replaced with a new one. For the case of using a Python script to run a never ending task, aSystemExitexception will be injected when a signal is received to shutdown the process. You can usesignal.signal()to register a signal handler forSIGTERMif needing to run special actions before then exiting the process usingsys.exit(), or to signal your own threads to exit any processing so you can shutdown in an orderly manner.
- display-name=value
Defines a different name to show for the daemon process when using the
pscommand to list processes. If the value is%{GROUP}then the name will be(wsgi:group)wheregroupis replaced with the name of the daemon process group.If this option is not specified, no rename is performed and the daemon process retains Apache’s default
argv[0](typically the path to thehttpdbinary), making it indistinguishable inpsoutput from the parent and child Apache processes. Setting this option, most commonly to%{GROUP}, is recommended so the daemon processes are clearly identifiable.Note that only as many characters of the supplied value can be displayed as were originally taken up by
argv0of the executing process. Anything in excess of this will be truncated.This feature may not work as described on all platforms. Typically it also requires a
psprogram with BSD heritage. Other programs which can display this value includehtop.
- home=directory
Defines an absolute path of a directory which should be used as the initial current working directory of the daemon processes within the process group.
If this option is not defined the initial current working directory will be set to be the home directory of the user that the daemon process is configured to run as using the
useroption to theWSGIDaemonProcessdirective. Otherwise the current working directory of Apache when started will be used, which if Apache is being started from system init scripts, would usually be the system root directory.
- user=name | user=#uid
Defines the UNIX user name or numeric user uid of the user that the daemon processes should be run as. If this option is not supplied the daemon processes will be run as the same user that Apache would run child processes, as defined by the User directive, and it is not necessary to set this to the Apache user yourself.
Note that this option is ignored if Apache wasn’t started as the root user, in which case no matter what the settings, the daemon processes will be run as the user that Apache was started as.
Also be aware that mod_wsgi will not allow you to run a daemon process group as the root user due to the security risk of running a web application as root.
- group=name | group=#gid
Defines the UNIX group name or numeric group gid of the primary group that the daemon processes should be run as. If this option is not supplied the daemon processes will be run as the same group that Apache would run child processes, as defined by the Group directive, and it is not necessary to set this to the Apache group yourself.
Note that this option is ignored if Apache wasn’t started as the root user, in which case no matter what the settings, the daemon processes will be run as the group that Apache was started as.
- supplementary-groups=group1 | supplementary-groups=group1,group2
Defines a list of additional UNIX groups that the user the daemon process group runs as, should be added to, in addition to primary UNIX group associated with that user. When specifying more than one group, separate the names of the groups with a comma.
- umask=0nnn
Defines a value to be used for the umask of the daemon processes within the process group. The value must be provided as an octal number.
If this option is not defined then the umask of the user that Apache is initially started as will be inherited by the process. Typically the inherited umask would be ‘0022’.
- lang=locale
Set the current language locale. This is the same as having set the
LANGenvironment variable.You will need to set this on many Linux systems where Apache when started up from system init scripts uses the default C locale, meaning that the default system encoding is ASCII. Unless you need a special language locale, set this to
en_US.UTF-8.Whether the
langorlocaleoption works best can depend on the system being used. Set both if you aren’t sure which is appropriate.
- locale=locale
Set the current language locale. This is the same as having set the
LC_ALLenvironment variable.You will need to set this on many Linux systems where Apache when started up from system init scripts uses the default C locale, meaning that the default system encoding is ASCII. Unless you need a special language locale, set this to
en_US.UTF-8.Whether the
langorlocaleoption works best can depend on the system being used. Set both if you aren’t sure which is appropriate.
- chroot=directory
Run the daemon process group process within a chroot jail. Use of a chroot jail is now deprecated due to the difficulty in setting up a chroot environment. It is recommended that you use modern containerisation technologies such as Docker instead.
- script-user=name | script-user=#uid
Sets the user that must be the owner of any WSGI script file delegated to be run in the daemon process group. If the owner doesn’t match a HTTP Forbidden response will be returned for any request.
Note that this doesn’t change what user the daemon process group runs as at any time. If you want to set the user that the daemon process group runs as, use the
useroption.Only one of
script-userorscript-groupoption can be used at the same time.
- script-group=name | script-group=#gid
Sets the group that must be the group of any WSGI script file delegated to be run in the daemon process group. If the group doesn’t match a HTTP Forbidden response will be returned for any request.
Note that this doesn’t change what group the daemon process group runs as at any time. If you want to set the group that the daemon process group runs as, use the
groupoption.Only one of
script-userorscript-groupoption can be used at the same time.
- python-home=directory
Set the location of the Python virtual environment to be used by the daemon processes. The directory to use is that which
sys.prefixis set to for the Python virtual environment. The virtual environment can have been created bypython -m venv,uv venv, orvirtualenv.Note that the Python virtual environment must have been created using the same base Python version as was used to compile the mod_wsgi module. You can’t use this to force mod_wsgi to somehow use a different Python version than it was compiled for. If you want to use a different version of Python, you will need to reinstall mod_wsgi, compiling it for the version you want.
This option is the daemon-mode equivalent of the WSGIPythonHome directive. See WSGIPythonHome for the full description.
- python-path=directory | python-path=directory:directory
List of colon separated directories to add to the Python module search path, ie.,
sys.path.Note that this is not strictly the same as having set the
PYTHONPATHenvironment variable when running normal command line Python. When this option is used, the directories are added by callingsite.addsitedir(). As well as adding the directory tosys.paththis function has the effect of opening and interpreting any.pthfiles located in the specified directories.If using a Python virtual environment, rather than use this option to refer to the
site-packagesdirectory of the Python virtual environment, you should use thepython-homeoption to specify the root of the Python virtual environment instead.In all cases, if the directory contains Python packages which have C extension components, those packages must have been installed using the same base Python version as was used to compile the mod_wsgi module. You should not mix packages from different Python versions or installations.
This option is the daemon-mode equivalent of the WSGIPythonPath directive. See WSGIPythonPath for the full description.
- python-eggs=directory
Directory to be used as the Python egg cache directory. This is equivalent to having set the
PYTHON_EGG_CACHEenvironment variable.Note that the directory specified must exist and be writable by the user that the daemon process run as.
This option is the daemon-mode equivalent of the WSGIPythonEggs directive. See WSGIPythonEggs for the full description.
- switch-interval=seconds
Override the Python GIL switch interval for the daemon process by calling
sys.setswitchinterval()once at process start. The value is a positive number of seconds expressed as a float (the same formsys.setswitchinterval()accepts), for exampleswitch-interval=0.002to set it to 2 ms.This option is the daemon-mode equivalent of the WSGISwitchInterval directive. See WSGISwitchInterval for the full description.
- restart-interval=sss
Defines a time limit in seconds for how long a daemon process should run before being restarted.
This might be used to periodically force restart the WSGI application processes when you have issues related to Python object reference count cycles, or incorrect use of in memory caching, which causes constant memory growth.
If this option is not defined, or is defined to be 0, then the daemon process will be persistent and will continue to service requests until Apache itself is restarted or shutdown.
Avoid setting this too low. This is because the constant restarting and reloading of your WSGI application may cause unnecessary load on your system and affect performance.
You can use the
graceful-timeoutoption in conjunction with this option to reduce the chances that an active request will be interrupted when a restart occurs due to the use of this option.
- maximum-requests=nnn
Defines a limit on the number of requests a daemon process should process before it is shutdown and restarted.
This might be use to periodically force restart the WSGI application processes when you have issues related to Python object reference count cycles, or incorrect use of in memory caching, which causes constant memory growth.
If this option is not defined, or is defined to be 0, then the daemon process will be persistent and will continue to service requests until Apache itself is restarted or shutdown.
Avoid setting this to a low number of requests on a site which handles a lot of traffic. This is because the constant restarting and reloading of your WSGI application may cause unnecessary load on your system and affect performance. Only use this option if you have no other choice due to a memory usage issue. Stop using it as soon as any memory issue has been resolved.
You can use the
graceful-timeoutoption in conjunction with this option to reduce the chances that an active request will be interrupted when a restart occurs due to the use of this option.
- inactivity-timeout=sss
Defines the maximum number of seconds allowed to pass before the daemon process is shutdown and restarted when the daemon process has entered an idle state. For the purposes of this option, being idle means there are no currently active requests and no new requests are being received.
This option exists to allow infrequently used applications running in a daemon process to be restarted, thus allowing memory being used to be reclaimed, with process size dropping back to the initial startup size before any application had been loaded or requests processed.
Note that after any restart of the WSGI application process, the WSGI application will need to be reloaded. This can mean that the first request received by a process after the process was restarted can be slower. If your WSGI application has a very high startup cost on CPU and time, it may not be a good idea to use the option.
See also the
request-timeoutoption for forcing a process restart when requests block for a specified period of time.
- request-timeout=sss
Defines the per-thread upper bound on how long a request can run before recovery is triggered. This is a process-level fail-safe for recovering from requests that block indefinitely; it is not a per-request SLA mechanism. Defaults to 0, meaning the timeout is disabled.
The actual fire point scales with the configured
threadsvalue by natural log:T_fire = request-timeout * (1 + ln(threads))
At
threads=1this collapses torequest-timeout. Atthreads=10it is ~3.3x; atthreads=25it is ~4.2x. The intent is to grant proportionally more patience as parallel capacity grows (a wedge in 1-of-10 threads costs less than a wedge in 1-of-1) without letting the threshold run away the way a linear scaling would. Each thread is judged independently against this threshold; multiple wedged threads are detected on the same schedule a single wedge would be.What happens at the fire point depends only on
interrupt-timeout. Withinterrupt-timeout=0(the default), mod_wsgi skips injection and transitions directly intograceful-timeout, thenshutdown-timeout. Withinterrupt-timeoutset to a non-zero value, mod_wsgi first attempts to interrupt only the offending thread by injecting amod_wsgi.RequestTimeoutexception; if that succeeds the process keeps running, and if it fails the samegraceful-timeout/shutdown-timeoutchain takes over. Seeinterrupt-timeoutfor the details of injection-based recovery.Sizing guidance: set
request-timeouta few times above the p99 of normal request duration — enough that steady-state traffic never trips it. The natural-log scaling already provides headroom for higher thread counts; do not pad the value further to compensate. For user-visible per-request deadlines (as distinct from a fail-safe) prefer application-level timeouts, such as HTTP client and database statement timeouts inside the request handler itself.Note that when a process is restarted due to a request timeout, if the Apache
LogLevelis set toinfoor higher, orwsgi:infoapplied forLogLevel, messages will be logged to the Apache error log file giving the Python stack trace for the offending request handler thread so you can work out where the request is blocking.The stack-trace dump is skipped when WSGIFreeThreading is active for the process. Walking interpreter thread frames relies on the GIL to keep those frames stable while they are being read, and that guarantee is gone when free-threading is active.
See also
deadlock-timeoutfor handling cases where a Python C extension wedges the GIL — the injection mechanism cannot recover those, butdeadlock-timeoutwill detect the wedge and restart the process.
- interrupt-timeout=sss
When non-zero, attempts to interrupt only the wedged thread when
request-timeoutfires by injecting amod_wsgi.RequestTimeoutexception, rather than immediately escalating to a process restart. Defines the grace window in seconds for the injected exception to land and the request to unwind. Defaults to 0 (disabled).This option only changes the recovery method taken when
request-timeoutfires. It does not change detection — the fire point set byrequest-timeoutis the same regardless of this setting.The injected exception derives directly from
BaseException, so well-written code usingexcept Exception:will not catch it. It may be caught for cleanup purposes but should be re-raised — swallowing it is counter to its purpose. If the exception unwinds back to the WSGI adapter within theinterrupt-timeoutgrace window, the adapter returns504 Gateway Timeoutand the worker thread returns to the pool to handle further requests. The process is not restarted; other threads were never disturbed. If the grace window expires with the same request still active, the daemon falls through tograceful-timeoutfollowed byshutdown-timeout.Recommended floor of ~10 seconds when enabled. Values significantly below that may not give the injected exception time to unwind through finally blocks, context managers, and the WSGI adapter.
Best-effort: the injection takes effect only when the target thread next runs Python bytecode. This has implications depending on what the thread is actually doing:
Thread running Python code (loops, computation, etc.): the exception fires on the next bytecode tick, almost immediately. This is the case the mechanism is designed for.
Thread blocked in a C call that has released the GIL (the common case — most socket reads, database driver calls,
time.sleep, file I/O, etc.): the injected exception is queued on the thread but does not fire until the blocking call returns and Python bytecode runs again. If the external service eventually responds or times out, the exception fires then. If the blocking call hangs indefinitely, the injected exception will never fire. In that case theinterrupt-timeoutgrace window will expire and the daemon process will be restarted via thegraceful-timeout/shutdown-timeoutfallback, taking the wedged request down with it. For user-visible per-request deadlines on external calls, prefer explicit application-level timeouts on the client itself (HTTP client read timeouts, database statement timeouts, etc.) — those bound the blocking call, which then letsinterrupt-timeoutdo its job cleanly.Thread blocked in a C extension that holds the GIL: the injection cannot even reach the thread, and no other Python thread can run either. This is what
deadlock-timeoutexists for.
When multiple threads wedge in quick succession each gets its own injection on its own grace timer (carried per-thread, not per process). The first injection grace to expire arms
graceful-timeout; sibling injections continue to tick on their own threads and may still unwind cleanly during the graceful window, in which case those threads free up and the drain check progresses.The
threads=0managed-process mode is unaffected — it has no requests and no per-thread timers.
- deadlock-timeout=sss
Defines the maximum number of seconds allowed to pass before the daemon process is shutdown and restarted after a potential deadlock on the Python GIL has been detected. The default is 300 seconds.
This option exists to combat the problem of a daemon process freezing as the result of a rogue Python C extension module which doesn’t properly release the Python GIL when entering into a blocking or long running operation.
- startup-timeout=sss
Defines the maximum number of seconds allowed to pass waiting to see if a WSGI script file can be loaded successfully by a daemon process. When the timeout is passed, the process will be restarted.
This can be used to force the reloading of a process when a transient issue occurs on the first attempt to load the WSGI script file, but subsequent attempts still fail because a Python package that was loaded has retained state that prevents attempts to run initialisation a second time within the same process. The Django package can cause this scenario as the initialisation of Django itself can no longer be attempted more than once in the same process.
- graceful-timeout=sss
When
maximum-requestsis used and the maximum has been reached, orcpu-time-limitis used and the CPU limit reached, orrestart-intervalis used and the time limit reached, orrequest-timeoutfires, ifgraceful-timeoutis set the process will continue to run for the number of seconds specified by this option, while still accepting new requests, to see if the process reaches an idle state. If the process reaches an idle state, it will then be restarted immediately. If the process doesn’t reach an idle state and the graceful restart timeout expires, the process will be restarted, even if it means that requests may be interrupted.The “idle state” check ignores any in-flight request whose elapsed time has already exceeded
request-timeout + interrupt-timeout. Such a request will not unwind voluntarily, so waiting for it before progressing toshutdown-timeoutserves no purpose. This is what allows graceful-timeout to complete promptly when a wedged thread is the only thing still tying up the process — sibling requests get the chance to finish cleanly while the wedged one rides out viashutdown-timeout’s forced kill.
- eviction-timeout=sss
When a daemon process is sent the graceful restart signal, usually
SIGUSR1, to restart a process, this timeout controls how many seconds the process will wait, while still accepting new requests, before it reaches an idle state with no active requests and shutdown.If this timeout is not specified, then the value of the
graceful-timeoutwill instead be used. If thegraceful-timeoutis not specified, then the restart when sent the graceful restart signal will instead happen immediately, with the process being forcibly killed, if necessary, when the shutdown timeout has expired.
- shutdown-timeout=sss
Defines the maximum number of seconds allowed to pass when waiting for a daemon process to shutdown. When this timeout has been reached the daemon process will be forced to exit even if there are still active requests or it is still running Python exit functions. No new requests are accepted while the shutdown timeout is being applied.
The shutdown timeout is applied after any other trigger has decided that the process should exit, regardless of which trigger initiated the shutdown. This includes:
graceful-timeoutexpiry (frommaximum-requests,restart-interval,cpu-time-limit, or the Apache graceful restart signal in the absence ofeviction-timeout);eviction-timeoutexpiry (the Apache graceful restart signal witheviction-timeoutset);request-timeoutfiring (wheninterrupt-timeoutis 0 and so injection is skipped) orinterrupt-timeoutgrace window expiry — both paths run viagraceful-timeoutwhen it is set and the process still has non-stale active requests, otherwise they proceed straight to shutdown;deadlock-timeoutfiring;inactivity-timeoutandstartup-timeoutfiring;external
SIGTERM/SIGINTfrom Apache parent or operator.
The wait given to in-flight requests on other threads to finish cleanly is
graceful-timeout, notshutdown-timeout. Once shutdown is actually under way,shutdown-timeoutis the hard cutoff before the process is force-killed regardless of remaining state. The default of 5 seconds suits most workloads — too short and Pythonatexithandlers or framework shutdown hooks may not finish cleanly; too long and recovery from a wedged process is delayed.If this option is not defined, then the shutdown timeout will be set to 5 seconds. Note that this option does not change the shutdown timeout applied to daemon processes when Apache itself is being stopped or restarted. That timeout value is defined internally to Apache as 3 seconds and cannot be overridden.
- connect-timeout=sss
Defines the maximum amount of time for an Apache child process to wait trying to get a successful connection to the mod_wsgi daemon processes. This defaults to 15 seconds.
- socket-timeout=sss
Defines the timeout on individual reads/writes on the socket connection between the Apache child processes and the mod_wsgi daemon processes. If this is not specified, the number of seconds specified by the Apache Timeout directive will be used instead.
- queue-timeout=sss
Defines the timeout on how long to wait for a mod_wsgi daemon process to accept a request for processing.
This option is to allow one to control what to do when backlogging of requests occurs. If the daemon process is overloaded and getting behind, then it is more than likely that a user will have given up on the request anyway if they have to wait too long. This option allows you to specify that a request that was queued up waiting for too long is discarded, allowing any transient backlog to be quickly discarded and not simply cause the daemon process to become even more backlogged. When this occurs the user will recieve a 504 Gateway Timeout response.
- listen-backlog=nnn
Defines the depth of the daemon process socket listener queue. By default the limit is 100, although this is actually a hint, as different operating systems can have different limits on the maximum value or otherwise treat it in special ways.
This option can be set, along with
queue-timeoutto try and better handle back logging when the WSGI application gets overloaded.
- socket-user=name | socket-user=#uid
Set the owner of the UNIX listener socket for the daemon process group.
This can be used when using the Apache PrivilegesMode directive with value of
SECUREto change the owner of the socket from the default Apache user, to the user under which the Apache child process which is attempting to connect to the daemon process group, will run when handling requests. This is necessary otherwise the Apache child worker process will not be able to connect to the listener socket for the mod_wsgi daemon process to proxy the request to the WSGI application.This option can also be used when using third party Apache modules such as mod_ruid, mod_ruid2, mod_suid as well as the ITK MPM for Apache.
- cpu-time-limit=sss
Define the maximum amount of CPU time a daemon process is allowed to consume before a shutdown is triggered and the daemon process restarted. The point of this is to provide some means of controlling potentially run away processes due to bad code that gets stuck in heavy processing loops.
Note that CPU time used is recorded from when the daemon process is first created. This means that a process will eventually reach the limit in normal use and would be restarted. You can use the
graceful-timeoutoption to reduce the chances that an active request will be interrupted.
- cpu-priority=num
Sets the scheduling priority set to the daemon processes. This can be a number of the range -20 to 20. The default priority is 0. A lower priority gives more favourable scheduling.
- memory-limit=num
Sets the maximum amount of memory a daemon process can use. This will have no affect on some platforms as
RLIMIT_AS/RLIMIT_DATAwithsetrlimit()isn’t always implemented. For example macOS does not implement this feature. You will need to test whether this feature works or not before depending on it.
- virtual-memory-limit=num
Sets the maximum amount of virtual memory a daemon process can use. This will have no affect on some platforms as
RLIMIT_VMEMwithsetrlimit()isn’t always implemented. You will need to test whether this feature works or not before depending on it.
- stack-size=nnn
The amount of virtual memory in bytes to be allocated for the stack corresponding to each thread created by mod_wsgi in a daemon process.
This option would be used when running Linux in a VPS system which has been configured with a quite low ‘Memory Limit’ in relation to the ‘Context RSS’ and ‘Max RSS Memory’ limits. In particular, the default stack size for threads under Linux is 8MB is quite excessive and could for such a VPS result in the ‘Memory Limit’ being exceeded before the RSS limits were exceeded. In this situation, the stack size should be dropped down to be in the region of 512KB (524288 bytes).
- receive-buffer-size=nnn
Defines the UNIX socket buffer size for data being received by the daemon process from the Apache child process.
This option may need to be used to override small default values set by certain operating systems and would help avoid possibility of deadlock between Apache child process and daemon process when the WSGI application generates large responses but doesn’t consume request content. In general such deadlock problems would not arise with well behaved WSGI applications, but some spam bots attempting to post data to web sites are known to trigger the problem.
The maximum possible value that can be set for the buffer size is operating system dependent and will need to be calculated through trial and error.
- send-buffer-size=nnn
Defines the UNIX socket buffer size for data being sent in the direction daemon process back to Apache child process.
This option may need to be used to override small default values set by certain operating systems and would help avoid possibility of deadlock between Apache child process and daemon process when the WSGI application generates large responses but doesn’t consume request content. In general such deadlock problems would not arise with well behaved WSGI applications, but some spam bots attempting to post data to web sites are known to trigger the problem.
The maximum possible value that can be set for the buffer size is operating system dependent and will need to be calculated through trial and error.
- header-buffer-size=nnn
Defines the maximum size that a response header/value can be that is returned from a WSGI application. The default size is 32768 bytes. This might need to be overridden where excessively large response headers are returned, such as in custom authentication challenge schemes which use the
WWW-Authenticateheader.
- response-buffer-size=nnn
Acts as a coarse upper bound, in bytes, on how much response content is passed down the output filter chain without a flush when proxying a response body from the WSGI application. If this many bytes are passed without a flush occurring for another reason, a flush is forced. The default is 8388608 bytes (8 MB), and if specified the value must be at least 65536 bytes.
Its only purpose is to bound a downstream output filter that buffers response data without draining it, capping such buffering to roughly this many bytes per request. The Apache core output filter already bounds normal in-memory buffering of the response in the Apache child processes, so the default is set high and the guard does not affect normal operation. Setting it low forces frequent flushes that can interfere with a downstream pacing or batching output filter such as
mod_ratelimit(seeresponse-flush-delay), so it should only be reduced if you specifically need to cap such a filter.
- response-socket-timeout=nnn
Defines the maximum number of seconds allowed to pass before timing out on a write operation back to the HTTP client when transferring the response body. Defaults to 0 seconds indicating that it will default to the value of the
socket-timeoutoption.
- response-flush-delay=nnn
Defines, in milliseconds, how long mod_wsgi will wait for further response data to arrive from the daemon process before flushing the data already read out to the HTTP client. Defaults to 5 milliseconds.
When proxying a response back from a daemon process, mod_wsgi reads the data as it becomes available and would otherwise flush to the client every time the daemon socket momentarily ran dry. During a bulk transfer that emptying is usually just an artefact of timing, and flushing on it defeats a downstream output filter that paces or batches data, most notably
mod_ratelimit(whoseRATE_LIMITfilter is forced to emit a short write on every flush and so throttles the response far below the configured rate). Waiting a brief period for more data lets mod_wsgi coalesce it into larger writes so such a filter can do its job, while a genuinely idle application still has its partial output flushed within the delay so streaming responses remain responsive.The default of 5 milliseconds is comfortably longer than the time it takes the local daemon process to produce more data during an active transfer, so it does not affect throughput, while bounding any extra latency added to a paused streaming response to that same small value.
Setting the value to 0 disables the wait, so data is flushed on any momentary stall. This is generally not recommended. In particular, do not set it to 0 when a downstream pacing or batching output filter such as
mod_ratelimitis in use: doing so reintroduces a flush on every momentary stall, which prevents such a filter from accumulating full-size writes and can throttle responses far below the configured rate. A value of 0 is only appropriate for latency-sensitive streaming where no such filter is present and even a few milliseconds of flush delay must be avoided.Note that, unlike the various
*-timeoutoptions which are expressed in seconds, this option is expressed in milliseconds because the useful values are far smaller than one second.
- server-metrics=on|off
Controls whether code running in this daemon process group is allowed to read Apache scoreboard data via the
mod_wsgi.server_metrics()Python API. Defaults tooff.This option is the daemon-mode equivalent of the WSGIServerMetrics directive, and is independent of it: the server-wide directive does not propagate to daemon process groups as a default, so each daemon group that should have scoreboard access must opt in explicitly via this option. See WSGIServerMetrics for the full description of what
mod_wsgi.server_metrics()returns and the information-disclosure considerations of opening up access to it.
To delegate a particular WSGI application to run in a named set of daemon
processes, the WSGIProcessGroup directive should be specified in
appropriate context for that application, or the process-group option
used on the WSGIScriptAlias directive. If neither is used to delegate
the WSGI application to run in a daemon process group, the application will
be run within the standard Apache child processes.
If the WSGIDaemonProcess directive is specified outside of all virtual
host containers, any WSGI application can be delegated to be run within
that daemon process group. If the WSGIDaemonProcess directive is
specified within a virtual host container, only WSGI applications
associated with virtual hosts with the same server name as that virtual
host can be delegated to that set of daemon processes.
In the case where you have two separate VirtualHost definitions for
the same ServerName, but where one is for port 80 and the other for
port 443, specify the WSGIDaemonProcess directive in the
first VirtualHost. You can then refer to that daemon process group
by name from the second VirtualHost. Using one daemon process group
across the two virtual hosts in this case is preferred as then you do not
have two whole separate instances of your application for port 80 and 443.
<VirtualHost *:80>
ServerName www.site1.com
WSGIDaemonProcess www.site1.com user=joe group=joe processes=2 threads=25
WSGIProcessGroup www.site1.com
...
</VirtualHost>
<VirtualHost *:443>
ServerName www.site1.com
WSGIProcessGroup www.site1.com
...
</VirtualHost>
When WSGIDaemonProcess is associated with a virtual host, the error log
associated with that virtual host will be used for all Apache error log
output from mod_wsgi rather than it appear in the main Apache error log.
For example, if a server is hosting two virtual hosts and it is desired that the WSGI applications related to each virtual host run in distinct processes of their own and as a user which is the owner of that virtual host, the following could be used:
<VirtualHost *:80>
ServerName www.site1.com
CustomLog logs/www.site1.com-access_log common
ErrorLog logs/ww.site1.com-error_log
WSGIDaemonProcess www.site1.com user=joe group=joe processes=2 threads=25
WSGIProcessGroup www.site1.com
...
</VirtualHost>
<VirtualHost *:80>
ServerName www.site2.com
CustomLog logs/www.site2.com-access_log common
ErrorLog logs/www.site2.com-error_log
WSGIDaemonProcess www.site2.com user=bob group=bob processes=2 threads=25
WSGIProcessGroup www.site2.com
...
</VirtualHost>
For historical reasons and the inability to change existing behaviour when
adding or changing features, many of the options to WSGIDaemonProcess,
especially those related to timeouts are not enabled by default. It is
strongly recommended you explicitly set these options yourself as this will
give you a system which is better able to recover from backlogging due to
overloading when you have too many long running requests or hanging
requests. As a starting point you can see what mod_wsgi-express uses as
defaults, adjusting them as necessary to suit your specific application
after you research what each option does. For example, consider starting
out with:
display-name='%{GROUP}'lang='en_US.UTF-8'locale='en_US.UTF-8'threads=5queue-timeout=45socket-timeout=60connect-timeout=15request-timeout=60interrupt-timeout=0inactivity-timeout=0startup-timeout=15deadlock-timeout=60graceful-timeout=15eviction-timeout=0restart-interval=0shutdown-timeout=5maximum-requests=0
Note that the WSGIDaemonProcess directive and corresponding features are
not available on Windows.
For the conceptual model behind daemon mode, the patterns for
choosing process and thread counts, and the interaction with
WSGIProcessGroup and WSGIApplicationGroup, see
Embedded and Daemon Mode. For a walkthrough of where
each of the timeout options above applies in the request flow
and what the recovery path looks like when one fires, see
Request Pipeline And Timeouts.