The frozen dataclass that controls all server behavior
11 min read2215 words
Overview
ServerConfig is a frozen dataclass (@dataclass(frozen=True, slots=True))
that holds all server settings. It's created once at startup and shared across
workers as frozen server configuration. Treat referenced objects as read-only
unless their own API says otherwise.
Not every knob carries the same maturity. Use the tier to decide what to lean on
in production. The same classification is surfaced programmatically:
pounce config schema stamps an x-stabilityannotation on each beta field.
Tier
Meaning
Stable
Covered by the core contract. Safe for production; behavior changes follow deprecation policy.
Beta
Usable, but the behavior, surface, or proof is still firming up. Pin versions and validate in staging before relying on it.
Stable knobs:host/port/uds, workers/backlog, all worker_mode
values (auto/sync/async/subinterpreter), the timeouts (*_timeout),
the limits (max_*), and logging (access_log/log_level/log_format).
Beta knobs: rate limiting (rate_limit_*), request queueing
(request_queue_*), introspection
(introspection_*), HTTP/3 (http3_*), and the observability integrations
(otel_*, sentry_*, metrics_*).
Note
Beta is about maturity, not safety: beta knobs are off by default and removable
from the request path when disabled. Inspect the live classification with
pounce config schema (look for "x-stability": "beta").
Worker count. 0 = auto-detect from CPU cores. 1 = single-worker (no supervisor). 2+ = multi-worker with supervisor.
worker_mode
str
"auto"
With multiple workers,auto resolves to sync threads on 3.14t and async processes on a GIL build. workers=1 uses direct async unless explicit subinterpreter(stable ASGI web-worker path; import path and compatible dependencies required).
worker_startup_failure
str
"ignore"
Worker-hook failure policy:ignore logs and serves for generic ASGI compatibility; shutdown fails boot with POUNCE_WORKER_STARTUP_FAILEDbefore readiness.
backlog
int
2048
Socket listen backlog
cpu_affinity
bool
False
Pin each worker to a CPU core (Linux only, reduces cache thrashing)
executor_threads_per_worker
int
0
Per-worker thread pool size forasyncio.to_thread(). 0 = auto-size.
Warning
On a GIL build,workers=2+ uses fork. State created during module import,
Serverconstruction, or main lifespan startup must be fork-safe. Initialize
process-local resources inpounce.worker.startupwith
worker_startup_failure="shutdown", or use workers=1. See
Workers for the complete contract.
Timeouts
Field
Type
Default
Description
keep_alive_timeout
float
5.0
Seconds to keep an idle HTTP connection open between requests
header_timeout
float
10.0
Seconds to receive complete request headers (slowloris protection)
request_timeout
float
30.0
Maximum seconds to wait for the next request-body event
write_timeout
float
30.0
Maximum seconds for blocked HTTP/1.1, HTTP/2, or WebSocket response delivery
startup_timeout
float
30.0
Maximum seconds to wait for server startup
shutdown_timeout
float
10.0
Seconds per worker join during shutdown (parallel in multi-worker)
Limits
Field
Type
Default
Description
max_request_size
int
1,048,576
Maximum request body (1 MB)
max_header_size
int
65,536
Maximum total header size (64 KB)
max_headers
int
100
Maximum number of headers
max_connections
int
10,000
Maximum concurrent connections
max_requests_per_connection
int
0
Max requests per keep-alive connection (0 = unlimited)
Logging
Field
Type
Default
Description
access_log
bool
True
Enable access logging
log_level
str
"info"
Log level: debug, info, warning, error, critical
log_format
str
"auto"
Log output format:auto (pretty on TTY, JSON when piped), text, or json
display
DisplayConfig | None
None
Optional startup display configuration.
app_name
str | None
None
App name merged into startup display configuration.
app_tagline
str | None
None
App tagline merged into startup display configuration.
app_version
str | None
None
App version merged into startup display configuration.
Advertise h2 via TLS ALPN when the optional dependency is installed; set false to force H1 at a Pounce-owned TLS origin
server_header
str
"pounce"
Value of theServerresponse header
date_header
bool
True
IncludeDateresponse header
root_path
str
""
ASGI root_path for reverse proxy setups
Compression
Field
Type
Default
Description
compression
bool
True
Enable content-encoding negotiation
compression_min_size
int
500
Minimum response size in bytes to compress
Observability
Field
Type
Default
Description
server_timing
bool
False
InjectServer-Timingheader with parse/app/encode durations
health_check_path
str | None
None
Path for the built-in readiness endpoint (recommended:"/readyz"). Returns 503 while draining; disabled by default.
introspection_enabled
bool
False
Enable the built-in/_pounce/infoendpoint.
introspection_bind
str
"127.0.0.1"
Warning-policy bind value for introspection exposure.
introspection_path
str
"/_pounce/info"
Path for the built-in introspection endpoint.
Note
Request IDs are always generated (or extracted from trusted proxies). Every response includes anX-Request-ID header for tracing, and requests from trusted proxies that send X-Request-IDhave their IDs honoured.
Development
Field
Type
Default
Description
debug
bool
False
Enable rich error pages (never use in production)
reload
bool
False
Watch source files and restart workers on changes
reload_include
tuple[str, ...]
()
Extra file extensions to watch beyond the default set (e.g.(".rst", ".scss"))
reload_dirs
tuple[str, ...]
()
Extra directories to watch alongside the current working directory
Whenreload is enabled, the default watch set is .py, .pyi, .yaml,
.yml, .toml, .json, .cfg, .ini, .md, .html, .css, .js, .svg.
Static-site authoring edits (Markdown, HTML, CSS, JS, SVG) therefore trigger a
reload withoutreload_include. The watcher scans the current working
directory, everyreload_dirsentry, and the directories behind any
configuredstatic_filesmounts; assets stored elsewhere need a matching
reload_dirsentry.
Trusted proxy hosts for X-Forwarded-* header validation (empty = strip all proxy headers). Accepts any iterable; normalized to frozenset internally.
forwarded_for_trusted_hops
int
1
Number of trusted proxy hops used to select the client address from the right side ofX-Forwarded-For. Must be at least 1.
Note
Whentrusted_hosts is empty, Pounce strips X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host from all requests. Set it to your reverse proxy's IP (e.g. frozenset({"10.0.0.1"})). Trusted X-Forwarded-Host rewrites both scope["server"] and the ASGI Hostheader, including a forwarded port when present. Tuples and lists are also accepted and converted automatically. A wildcard trusts every direct peer and is unsafe on an internet-reachable listener.
X-Real-IP is not used to rewrite scope["client"]; only a trusted peer's
X-Forwarded-Forparticipates in Pounce client-address normalization.
TLS
Field
Type
Default
Description
ssl_certfile
str | None
None
Path to TLS certificate file
ssl_keyfile
str | None
None
Path to TLS private key file
Note
ssl_certfile and ssl_keyfile must both be set or both be None. Setting only one raises ValueError.
Extended Fields
These fields control optional features. Most have sensible defaults and don't need to be set for basic usage.
Static Files
Field
Type
Default
Description
static_files
dict[str, str]
{}
URL path to directory mapping (e.g.{"/static": "./public"})
static_cache_control
str
"public, max-age=3600"
Cache-Control header for static files
static_precompressed
bool
True
Serve.zst/.gzpre-compressed variants when available
static_follow_symlinks
bool
False
Allow following symlinks (keep disabled in production)
Accept TLS 0-RTT at the transport layer; unsafe methods receive 425.
Reload
Field
Type
Default
Description
reload_timeout
float
30.0
Time to wait for workers to drain during reload
OpenTelemetry
Field
Type
Default
Description
otel_endpoint
str | None
None
OTLP endpoint (e.g."http://localhost:4318")
otel_service_name
str
"pounce"
Service name in traces
Lifecycle Logging
Field
Type
Default
Description
lifecycle_logging
bool
False
Enable structured lifecycle event logging
log_slow_requests_threshold
float
5.0
Log requests slower than this (seconds)
Prometheus Metrics
Field
Type
Default
Description
metrics_enabled
bool
False
Enable Prometheus metrics endpoint
metrics_path
str
"/metrics"
Path for metrics endpoint
Rate Limiting
Field
Type
Default
Description
rate_limit_enabled
bool
False
Enable per-IP rate limiting (enforced per worker)
rate_limit_requests_per_second
float
100.0
Requests per second per IP, per worker
rate_limit_burst
int
200
Maximum burst size per IP, per worker
These limits are enforced per worker (shared only in thread mode); withworkers > 1 the aggregate per-IP ceiling is rate x workers. See Backpressure.
Request Queueing
Field
Type
Default
Description
request_queue_enabled
bool
False
Enable request queueing and load shedding (per worker)
request_queue_max_depth
int
1000
Maximum queued requests per worker (0 = unlimited)
The queue is per worker in every mode (it uses a per-event-loopasyncio.Semaphore), so the effective shed depth is max_depth x workers. See Backpressure.