Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,059 of 9,059 pages
About the help in other languages
All help pages

Specification: Velocity engine settings and programs

This page is the reference for the Velocity engine's own settings (JSON under the Q key), where they are read from, the programs the engine ships, logging, branding, the event loop, TLS session reuse and the start-up…

Download as PDF

Address: https://doc.exponential.earth/exphelp/viewer/specifications/6.0/velocity-engine-settings.md

On this page

Specification: Velocity engine settings and programs

This page is the reference for the Velocity engine's own settings (JSON under the Q key), where they are read from, the programs the engine ships, logging, branding, the event loop, TLS session reuse and the start-up pre-warm cache. Read it when you configure Velocity outside Exponential's settings/velocity.ini, read its logs, or need the default of an engine key. It applies to Exponential Velocity 0.0.4.42.

From Exponential, the engine is normally configured through settings/velocity.ini; see Velocity engines. The settings of larger subsystems have their own pages: response cache, HTTPS, control panel, Q shell, worker pool, headers and limits.

In the tables below, a key without the Q. prefix is relative to Q (webserver.keepAlive.max is Q.webserver.keepAlive.max).

Where settings come from

Settings are JSON under the Q key. They are read in this order, and a later source wins: the engine's built-in defaults; the configuration tree (qbix.conf, ports.conf, conf-enabled/, mods-enabled/, sites-enabled/, in /etc/qbix, with overlays such as /etc/vc stacked on top); the file given by --config; and the control panel's store (only for the settings the panel offers).

To print what would be loaded, without starting the server:

php sbin/qbixserver.php --root=web --layout
php sbin/qbixserver.php --root=web -t --config=/etc/qbix/sites-enabled/default.conf
OptionMeaning
--conf-dir=DIRA configuration directory laid out like /etc/apache2 (auto is /etc/qbix with overlays)
--config=FILEA JSON site file, usually DIR/sites-enabled/SITE.conf
--distribution=NAMELoad Q_WebServer_Distribution_NAME's additions (default: QBIX_DISTRIBUTION, then the DISTRIBUTION file). Velocity's distribution is vc, which stacks /etc/vc on /etc/qbix
--layoutPrint the configuration files that would be loaded, and exit

The tree: qbix.conf (base, like apache2.conf), ports.conf (listen ports), envvars (environment of the server process, including QBIX_RUN_USER and QBIX_RUN_GROUP), conf-available/ and conf-enabled/, mods-available/ and mods-enabled/, sites-available/ and sites-enabled/ (enabled by symlink), designs/, ssl/, acl/. State lives in /var/lib/qbix (/var/lib/vc), logs in /var/log/qbix (/var/log/vc). Details and the migration of an existing installation: Velocity on-disk layout.

Programs

ProgramWhat
sbin/qbixserver.php (phar: sbin/qbixserver.phar)The server
sbin/qbixctl.phpstart, stop, restart, graceful, status, -t, -S, ensite, dissite, enconf, disconf, enmod, dismod, panel:password, panel:check, panel:2fa, ext:*, ssl:*
sbin/qbixconsole.phpEvery console command; qbixconsole list, qbixconsole help <command>
bin/qshell.php (vc-qshell when installed from a package)The Q shell at a terminal
sbin/uwebserverThe small C static file server

Since 0.0.4.41 the daemon and its administration commands are in sbin/ and the user commands in bin/. Every former path (qbixserver.php, qbixctl.php, qbixconsole.php, qshell.php at the top of the tree, bin/qbixserver.phar, bin/uwebserver) is a forwarder that runs the new file in the same process (same command line, process id and title, standard streams and exit status). A forwarder prints a note on standard error only when it is a terminal; QBIX_MOVED_QUIET=1 silences it. Composer's bin lists the four sbin/ and bin/ PHP programs.

All programs accept --name=value, --name value, -name=value, -name value, bundled one-letter flags and --no-flag, and --version, -version, -v, -V, --about, --copyright (release, build, where it runs from, PHP, system and extensions, licence).

qbixctl restart and logs

qbixctl restart restarts with the options the server was started with: a server started with a pid file writes how it was started beside it (<pid file>.json: the command line, the interpreter's -d settings, the start directory, the QBIX_*, *_CONF_DIR, *_STATE_DIR, *_DISTRIBUTION, *_RUN_USER and *_RUN_GROUP variables, and the output file). Options given to restart replace the recorded ones (qbixctl restart --workers=16); anything after -- is added. Without --log, the server's output goes to Q.webserver.log.dir, else var/log, files/log or logs of the document root or the directory above it, else the configuration tree's log directory (/var/log/qbix, /var/log/vc for Velocity, or QBIX_LOG_DIR), else var/log beside the document root; never the temporary directory. qbixctl status, stop and graceful find a running server without its pid file.

General server settings (Q.webserver and Q)

KeyDefaultWhat it does
webserver.keepAlive.max100Max requests per keep-alive connection; the last one and any 5xx are answered Connection: close
webserver.keepAlive.timeout15Seconds before an idle connection is closed
webserver.maxConnections1024Max simultaneous connections; beyond it 503
webserver.fileCache.maxSize64MBMemory for cached file responses; the least recently used file makes room when full
webserver.fileCache.maxFile1MBLargest file kept in memory
webserver.fileCache.checkInterval1Seconds between file modification checks
webserver.rateLimit.enabled, .requests, .windowfalse, 100, 60Per-IP rate limiting
webserver.requestTimeout30Seconds a request may run before 504; 0 no limit
webserver.workerMemoryCeiling256 MB or 3/4 of memory_limitHeap past which a worker is replaced
webserver.warmupnoneScript run once in the parent after the transform, before forking
webserver.eventLoopautoauto, iopoll, revolt, select; QBIX_EVENT_LOOP overrides
webserver.reusePortfalseSO_REUSEPORT so several servers share a port
webserver.debugfalseShow an uncaught error's message, class, file, line and trace in the response; off, the application's exception handler runs, else the designed 500 page
webserver.followSymlinksfalseFollow links that leave the document root
webserver.hosts.<host>.rootthe default rootPer-host document root (selected by Host)
webserver.hosts.<host>.lognonetrue for <host>-access.log and <host>-error.log in the server's log directory, or an object that overrides dir, accessName, errorName, fileMode, dirMode
webserver.headers, headersOnScripts, hstssee securityHeaders on every response
webserver.scripts, frontControllers; web.static.pathsallWhich scripts run by name, which file is the front controller, which files are sent as they are (opt-in lists)
webserver.fallbacknoneCatch-all: "index.html", {"handler":"app/notfound"} or {"file":"404.html"}
webserver.hotReloadfalseWatch classes/, handlers/, config/; restart on change (--hotreload)
webserver.cgi.patterns, webserver.cgi.binary[], autoScripts that need php-cgi, and its path
webserver.user, group, allowRootWorkerssee worker poolWho workers run as
webserver.brand, brandUrl, maintainer, maintainerUrlQbix Server, empty, empty, emptyThe product name and optional links shown on the server's own views; a URL that is not http or https is dropped
dashboardenabledfalse disables /Q/dashboard, /Q/health, /Q/ws
dashboard.tokennoneRequire ?token=VALUE
dashboard.hidePanelRequestsfalseLeave /Q/ requests out of the dashboard
autoload.psr-4, autoload.psr-0{}Namespace maps, for example {"App\\": "src/"}
socket.io, socket.js/socket.io, /Q/socket.jsSocket.IO endpoint and the minimal WebSocket client path; false disables
appemptyApp name that prefixes handler function names
compat.statTtl0See worker pool
log.*no log without itThe access and error log, see "Logging" below. The logs are written only when Q.webserver.log is present

Logging

Settings under Q.webserver.log (checked against Q_WebServer_Log in the engine; nothing is logged until the block exists, even an empty-looking one such as {"dir": "logs"}). From Exponential, [LogSettings] in settings/velocity.ini writes this block for you (its Format default is combined, not the engine's vhost).

KeyDefaultMeaning
dir<app>/logs, else logsDirectory of the log files
access, errortrue, trueSwitch one of the two logs off with false
accessName, errorNameaccess.log, error.logFile names: a bare name, no directory part (anything else falls back to the default, so a name cannot write outside dir)
formatvhostvhost, qbix, combined, common or a format string with Apache tokens (%h %t %r %>s %b %D %T %{ms}T %{Name}i and others)
bufferSize65536Bytes buffered before a write; 0 writes every line
flushInterval1Seconds between timed flushes
maxSize52428800Size at which a file is rotated
archiveAfterDays2Older logs are compressed to .gz
deleteAfterDays30Older logs are deleted
fileMode, dirMode0666 less umask, 0755Permissions; 0640 and 0750 keep other accounts from reading who visited

Rotation is daily and inserts the date before .log (site.log becomes site.2000-10-10.log). A virtual host logs to its own files by adding log to its webserver.hosts.<host> entry (true, or an object that overrides dir, accessName, errorName, fileMode, dirMode); a request for a host without one goes to the server's log. Named formats: common is %h %l %u %t "%r" %>s %b; combined adds the referrer and user agent; qbix adds the time in milliseconds; vhost adds the host name in quotes.

The access log

Since 0.0.4.28 the default format is vhost: the older qbix line plus the host name, in quotes, at the end. A log reader anchored at the end of the line (fail2ban, a GoAccess custom format) needs updating, or set {"Q":{"webserver":{"log":{"format":"qbix"}}}} to keep the old lines. Pooled responses are logged when they go out, not when dispatched (0.0.3.1), and the line no longer claims HTTP/1.1 for other protocols. Each host's files rotate, archive and prune on the same terms as the server's own; the dashboard's log viewer takes ?host=.

Presets

--preset=NAME with laravel, symfony, wordpress, drupal, exponential. A preset carries a _webserver block that merges under Q.webserver (that is how the preset reaches keepGlobals). The exponential preset keeps the source transform on, preserves the type registries across requests, and brings Exponential's own script, front controller and static path lists when the configuration names none; lists that are configured are never widened.

Environment

VariableMeaning
QBIX_RUN_USER, QBIX_RUN_GROUP, QBIX_RUN_ALLOW_ROOT (VC_RUN_* first under Velocity)Who workers run as
QBIX_DISTRIBUTIONDistribution to load
QBIX_CONF_DIR, QBIX_STATE_DIR, QBIX_LOG_DIRDirectories
QBIX_EVENT_LOOPEvent loop backend
QBIX_SHIP_VERSIONAt phar build time: the version the archive shows (set to the release being cut)
QBIX_MOVED_QUIETSilence the forwarder note

Brand and the server's own pages

The names and marks shown on the server's own views (/Q/dashboard, /Q/panel, error pages, directory listings) come from Q.webserver (checked against Q_WebServer_Brand in the engine):

KeyDefaultMeaning
brandQbix ServerProduct name; shown in headers, titles and the control panel header
brandUrl, maintainer, maintainerUrlemptyLinks for the brand and a maintainer credit in the footer (only http and https URLs are kept)
brandDescriptionbuilt inText for link previews
brandIconnoneAn .svg, .png, .jpg or .ico file used as the icon of the pages
brandMarkfirst letter of the brandThe letter drawn on the generated icon
brandColor, brandAccent, brandBackground#7c8aff, #22d3ee, #0f1117Colours of the generated icon
brandFontsearch of common system fontsFont file for the generated raster icon

With the default brand and nothing set, the server's own logo is used. The pages also carry icons, a web app manifest and link previews (24 September 2026); every markup file is a design on disk (designs).

Event loop and TLS

webserver.eventLoop chooses the loop that waits for sockets: auto takes Revolt when revolt/event-loop is installed, else stream_select; iopoll (PHP's native Io\Poll) is opt-in because it has not been run against the real extension; QBIX_EVENT_LOOP overrides the setting. Revolt gains speed only with the ev, event or uv extension and measured no faster than select up to 2,000 connections; the ceiling below about 1,000 workers is that of stream_select (worker pool).

A TLS session can be resumed (22 September 2026): the HTTPS listener holds one context with the session cache and ticket key, and every accepted connection inherits it, so a returning visitor, and each new connection within a visit, skips the full handshake. Check against a Velocity HTTPS listener (not a front end such as Apache) with openssl s_client -connect host:443 -reconnect < /dev/null | grep -c Reused; more than 0 means sessions are resumed.

Start-up pre-warm cache

At start the compatibility layer walks the document root and tokenises every PHP file so workers inherit the results. Since 23 September 2026 the result is kept between starts (an Exponential tree of 5,000 files: 4.7 s down to 0.6 s). An entry is reused only when its size and modification time both still match; the file is dropped when the transformer, the PHP version or the root differs. The start-up line reports how many entries were reused: none reused on a second start means the cache could not be written.

KeyDefaultMeaning
Q.webserver.compat.persistPrewarmtrueKeep the result between starts
Q.webserver.compat.dirqbixserver-compat in the system temporary directoryWhere it is kept (created 0700, the file 0600: it holds transformed copies of your source)
Q.webserver.compat.dirMode0700Directory mode
Q.compat.skipSourceCodeTransformfalseTurn the source transform off (see the worker pool, "The compatibility layer")

Binding and files

Without --user and a configuration, a server started as root keeps root workers only when the document root belongs to root (the start-up says so). --socket=PATH listens on a Unix socket (mode --socket-mode, default 0660). Per-host and server log and cache files take fileMode and dirMode (defaults: files 0666 less the umask, directories 0755); for sites that each run as their own user, the host writing the file should own it.

Scheduler

The server runs handlers on a schedule, like cron, from Q.scheduler (introduced 21 July 2026): each task names a handler dispatched with Q::event() in a forked child, with every seconds, or times (HH:MM) narrowed by weekdays and monthdays. It is not a way to run a command-line PHP script. Scheduled tasks give up root like workers do. Fields, examples and limits: Velocity scheduler; the engine's own docs/configuration.md, section "Scheduler".

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x