cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
Runtime configuration

Every CWIST_* environment variable the framework reads is listed here. scripts/ci/check_env_knobs.py (make env-check, run in CI) fails when src/ reads a variable this page does not list, or when this page lists one src/ no longer reads, so the table stays complete.

Most variables are read once, on first use, and cached: set them before the process starts (or before cwist_app_listen()), not while it is serving. An empty or malformed value falls back to the default unless the row says otherwise.

Status

Each variable has one status. The status says what v4 promises about it.

Status Promise for the v4 series
supported The name and meaning stay. A supported variable is not removed or repurposed before v5; the CI check fails if one disappears after the v4 tag.
tuning The name stays, but the effect and the default may change between minor releases as the engine changes. Measure before relying on a value.
diagnostic For debugging only. Output format and behavior are not stable and may change or go away in any release.

Processes and server mode

Variable Status Values Default Effect
CWIST_WORKERS supported integer 1 Worker processes forked before the event loop.
CWIST_C1M_MODE supported 0 or false disables 1 1 serves on the CWIST reactor (C1M); 0 selects the classic thread pool.
CWIST_PROFILE supported default, performance, lowmem, lowlat default Preset that fills in other variables the environment leaves unset (explicit values win). default: CWIST_C1M_MODE=1, CWIST_REACTOR_DRAIN_CHUNK=8. performance: adds CWIST_MALLOC_ARENA_MAX=1, CWIST_HTTP_BATCH=64. lowmem: CWIST_C1M_MODE=1, CWIST_MALLOC_ARENA_MAX=1, CWIST_WORKERS=2. lowlat: CWIST_C1M_MODE=0. An unknown value warns and uses default.
CWIST_DRAIN_TIMEOUT supported seconds, 0–3600 5 How long shutdown waits for in-flight requests before the app is destroyed. Out of range values are reported on stderr and ignored.
CWIST_REUSEPORT supported 0 or false disables on SO_REUSEPORT on the TCP and UDP (HTTP/3) listen sockets, so a second process can bind the same port for a zero-downtime restart; see Zero-downtime restart. Disabling restores bind() failure on a port conflict, but worker processes re-bind the port after fork, so it requires CWIST_WORKERS=1.
CWIST_FD_LIMIT_TARGET supported integer > 0 1050000 Open-file soft limit the server raises itself to at start (capped by the hard limit). See C1M file limits.
CWIST_MALLOC_ARENA_MAX tuning integer ≥ 0 unset (glibc default) glibc only: mallopt(M_ARENA_MAX). 1 trades some allocator concurrency for a much lower RSS.
CWIST_MALLOC_TRIM_IDLE_SEC tuning seconds, 0–86400 30 glibc only (no-op elsewhere): seconds of cumulative event-free reactor idleness after which the reactor calls malloc_trim(0) on a zero-event wake, returning the free arena top to the OS. Runs only on idle wakes, so the hot path pays nothing. Measured ≈1.2 MiB median per worker after a load round. 0 disables the trim.

Classic thread pool

Variable Status Values Default Effect
CWIST_WORKER_THREADS supported integer > 0 CPU cores Base number of pool threads.
CWIST_POOL_PREWARM supported integer base pool size Threads spawned at start, when larger than the base pool (capped by the pool maximum). Avoids spawning during a connection ramp.
CWIST_POOL_IDLE_TIMEOUT_MS supported milliseconds ≥ 0 2000 How long a thread above the base pool idles before it exits. 0 keeps surplus threads forever.

HTTP/1.1

Variable Status Values Default Effect
CWIST_HTTP_KEEP_ALIVE_TIMEOUT supported seconds > 0 15 Idle time before a keep-alive connection is closed.
CWIST_ASYNC_STASH_IDLE_SEC tuning seconds ≥ 0 10 C1M async HTTP: seconds an oversized keep-alive rbuf/obuf stash must go unneeded before it is shrunk toward the 4 KiB floor at re-arm. Busy connections keep their capacity (no per-request shrink→regrow realloc); idle ones still converge to the floor, delayed by the window. 0 restores the legacy immediate shrink.
CWIST_HTTP_BATCH tuning 1–1024 16 Pipelined requests dispatched per event-loop turn; the rest continue on the next turn.
CWIST_HTTP_YIELD_BATCH tuning 1–1024 CWIST_HTTP_BATCH Requests served within a batch before the connection yields back to the reactor queue.
CWIST_USE_TCP_CORK tuning integer > 0 off Linux, cleartext HTTP/1.1: cork the socket so headers, body and file bytes go out in full segments.
CWIST_TCP_CORK_BURST tuning bytes ≥ 16384 262144 With CWIST_USE_TCP_CORK, a file body is flushed every this many bytes instead of in one clump.

HTTPS

Variable Status Values Default Effect
CWIST_HTTPS_IDLE_TIMEOUT_MS supported milliseconds > 0 30000 Idle time before an HTTPS connection is closed.
CWIST_HTTPS_PARK tuning 0/false disables on Park idle TLS connections in the reactor instead of holding a pool thread.
CWIST_HTTPS_HS_SHARDS tuning 1–16 CPU cores, clamped to 4–16 Handshake shards. For connect-burst tuning.
CWIST_TLS_SESS_CACHE_SIZE tuning integer, 0–1048576 1024 Cap on the BoringSSL server-side session cache (SSL_CTX_sess_set_cache_size), applied to every server TLS context (HTTP/1.1, HTTP/2, HTTP/3). Bounds TLS 1.2 session-ID retention per worker process. 0 leaves the BoringSSL default (uncapped). Consulted on session insert only.

HTTP/2

Variable Status Values Default Effect
CWIST_HTTP2_IDLE_TIMEOUT_MS supported milliseconds > 0 300000 Idle time before an HTTP/2 connection is closed.
CWIST_HTTP2_GOAWAY_GRACE_MS supported milliseconds ≥ 0 2000 Time between GOAWAY and closing the connection, so a client can finish streams it already started.
CWIST_HTTP2_MAX_RST_BURST supported integer > 0 100 Stream resets a client may send in a burst before the connection is closed (rapid reset defence, CVE-2023-44487).
CWIST_HTTP2_MAX_RST_RATE supported resets per second > 0 100 Refill rate of that reset budget.
CWIST_H2_BATCH_BYTES tuning bytes ≥ 4096 65536 Outgoing frames are coalesced and written once this many bytes are pending (or before any blocking wait).

HTTP/3

Variable Status Values Default Effect
CWIST_H3_NO_GSO tuning 1 off Linux: send each QUIC datagram separately instead of with UDP GSO.
CWIST_H3_DEBUG diagnostic set unset Routes lsquic's own log to stderr (CONNECTION_CLOSE codes and so on). Read when the server loop starts.

WebSocket

Variable Status Values Default Effect
CWIST_WS_ASYNC_IDLE_TIMEOUT_SEC supported seconds ≥ 0 300 Idle time before an async (reactor) WebSocket is closed. 0 never closes idle sockets.

Reactor

Variable Status Values Default Effect
CWIST_REACTOR_BACKEND tuning epoll io_uring Linux: force the epoll backend, for A/B measurement.
CWIST_RX_URING tuning 0 disables on Receive with IORING_OP_RECV instead of POLL + recv.
CWIST_ACCEPT_URING tuning 0 disables on Accept new connections with a multishot IORING_OP_ACCEPT instead of a one-shot POLL + accept4 drain loop. Kernels without multishot accept fall back to the poll loop silently.
CWIST_RX_EPOLL tuning 0 disables on On the epoll reactor (no io_uring ring, or CWIST_REACTOR_BACKEND=epoll), keep keep-alive connections registered edge-triggered and receive from the reactor, instead of re-arming a one-shot poll with epoll_ctl per request.
CWIST_REACTOR_DRAIN_CHUNK tuning integer ≥ 0 8 (set by CWIST_PROFILE; 64 without it) Connection callbacks handled between drains of posted work, on every reactor backend (io_uring, epoll, kqueue). 0 disables the mid-batch drain (legacy). See cooperative queuing.
CWIST_REACTOR_ROUND_BUDGET_US tuning microseconds ≥ 0 2000 Once a reactor round runs longer than this, parked re-arms are flushed to the kernel every 64 callbacks instead of at the end of the round. The round still runs to completion. 0 disables the bound.
CWIST_REACTOR_CQ_GRACE_NS tuning nanoseconds ≥ 0 20000 How long the reactor spins on the completion ring before it sleeps in the kernel. 0 disables the spin.

Diagnostics

Variable Status Values Default Effect
CWIST_ASYNC_DEBUG diagnostic set unset Log rare failures of the C1M async path and the reactor (rearm, submit, full SQ) to stderr. Silent in normal operation.
CWIST_ASYNC_STRICT diagnostic 1 unset Deferred-response misuse aborts (leaving a core) instead of printing one warning.
CWIST_LATENCY_PROBE diagnostic 1 unset Record arm-to-dispatch and callback-time histograms per reactor and print them to stderr when the reactor is destroyed (issue #166).