The hosting queue is a Redis list used to buffer incoming analytics, logs, and usage metrics before they are written to the database. A background worker drains this queue every 5 seconds.
| Variable | Default | Description |
|---|---|---|
STORMKIT_HOSTING_QUEUE_BATCH_SIZE |
1000 |
Number of items consumed from the hosting queue per worker run. Increase this value if the queue grows faster than it is being drained. |
By default Stormkit assumes it is the public edge: X-Forwarded-For is always overwritten with the real socket address, and X-Real-IP is overwritten if the client supplied one.
Choose the right mode based on the type of load balancer in front of Stormkit:
| Setup | Variable to enable |
|---|---|
| No load balancer (Stormkit is the public edge) | neither (default) |
| L7 HTTP load balancer (e.g. nginx, AWS ALB, Cloudflare) | STORMKIT_TRUST_PROXY_HEADERS=true |
| L4 TCP load balancer (e.g. AWS NLB, HAProxy in TCP mode) | STORMKIT_PROXY_PROTOCOL=true |
If Stormkit sits behind a trusted HTTP reverse proxy that sets X-Forwarded-For / X-Real-IP correctly, enable the following variable so that those headers are passed through unchanged:
| Variable | Default | Description |
|---|---|---|
STORMKIT_TRUST_PROXY_HEADERS |
false |
Set to true when Stormkit runs behind a trusted upstream HTTP proxy. X-Forwarded-For and X-Real-IP are passed through unchanged. When false (default), X-Forwarded-For is always overwritten with the real socket address. |
Stormkit reads the visitor's IP from the right of X-Forwarded-For, where your proxies append it. Walking from the right, it skips internal hops (private, loopback, link-local, CGNAT 100.64.0.0/10 and other non-routable addresses) and any proxy listed in STORMKIT_TRUSTED_PROXIES, and uses the first address left. Entries further left were sent by the client and are ignored, so a visitor cannot spoof their IP by sending the header themselves. If every entry is internal, as on an intranet-only install, the left-most address is used.
| Variable | Default | Description |
|---|---|---|
STORMKIT_TRUSTED_PROXIES |
empty | Comma-separated CIDRs or IPs of public proxies in front of Stormkit, such as a CDN. Their entries in X-Forwarded-For are skipped when looking for the visitor's IP. Invalid entries are logged and ignored. |
If you chain two public proxies (for example Cloudflare in front of a load balancer), every request reaches the load balancer from a Cloudflare address, which would otherwise be taken as the visitor's IP. Either set STORMKIT_TRUSTED_PROXIES to Cloudflare's published ranges:
STORMKIT_TRUSTED_PROXIES=173.245.48.0/20,103.21.244.0/22,104.16.0.0/13,2400:cb00::/32,...
or configure the load balancer to overwrite X-Forwarded-For with the visitor's IP (for example from CF-Connecting-IP) instead of appending to it.
TCP load balancers forward connections at the network level and cannot inject HTTP headers, so X-Forwarded-For will never be set. Instead, configure the load balancer to emit a PROXY protocol header (v1 or v2) at the start of each TCP connection, and enable the corresponding Stormkit flag:
| Variable | Default | Description |
|---|---|---|
STORMKIT_PROXY_PROTOCOL |
false |
Set to true when Stormkit runs behind a TCP load balancer that emits PROXY protocol headers. The real client IP is read from the TCP layer before TLS handshake. |
Security note: PROXY protocol headers are only trustworthy when Stormkit can be reached only through the trusted L4 load balancer. If the Stormkit port is directly reachable, a client can send a forged PROXY header and spoof the source IP. When
STORMKIT_PROXY_PROTOCOL=true, restrict inbound traffic to the Stormkit origin so that only the load balancer can connect (for example with security groups, firewall rules, or equivalent network controls).
Security note: It is not advised to enable
STORMKIT_PROXY_PROTOCOLandSTORMKIT_TRUST_PROXY_HEADERSat the same time as it will allow a client to spoof its source IP by injecting arbitraryX-Forwarded-Forheaders alongside a PROXY protocol header.
A redirect rule with an absolute target URL proxies the request. When that target is on this instance's dev domain (for example my-landing.stormkit.example.com), the proxied request connects to the same server over loopback instead of resolving the domain through DNS. It stays on the machine that received the visitor's request, so it doesn't go out through your load balancer and back in. The TLS server name and Host header are unchanged. Custom domains are always resolved through DNS, since they may point somewhere other than this instance, and so are http targets. Local dialling is skipped when STORMKIT_PROXY_PROTOCOL=true.
| Variable | Default | Description |
|---|---|---|
STORMKIT_PROXY_LOCAL_DIAL |
true |
Set to false to proxy every redirect target over the network, including dev-domain targets. |
A data loader on a rewrite rule fetches JSON from your API on every matching request. To stop a rule from reaching your cloud provider's metadata service or other internal services, loaders only accept https URLs and only connect to public IP addresses.
| Variable | Default | Description |
|---|---|---|
STORMKIT_PAGE_DATA_INSECURE |
false |
Set to true to allow loaders to use plain http URLs and connect to private, loopback and link-local addresses. Use it when your API is only reachable on a private network. |
Security note: With this enabled, anyone who can edit redirect rules can make Stormkit send requests to any service on its network. Only enable it when everyone with that access is trusted.
The following environment variables control the HTTP server timeouts. Values are parsed as Go duration strings; you should include a unit suffix (e.g. 30s, 1m, 500ms). Bare integers without a unit (e.g. 30) are interpreted as nanoseconds (e.g. 30 → 30ns), which results in an extremely short timeout and is almost never desired. When unset, the defaults shown below are used.
| Variable | Default | Description |
|---|---|---|
STORMKIT_HTTP_READ_TIMEOUT |
30s |
Maximum time to read an entire request, including the body. Used only for the API server; the hosting server uses STORMKIT_HTTP_CLIENT_BODY_TIMEOUT instead. |
STORMKIT_HTTP_IDLE_TIMEOUT |
60s |
Maximum time to wait for the next request on a keep-alive connection. |
STORMKIT_HTTP_CLIENT_BODY_TIMEOUT |
60s |
Maximum idle time between successive reads of an incoming request body. Equivalent to nginx's client_body_timeout. If no bytes arrive within this window, body reads time out. Set to 0 to disable. |
STORMKIT_HTTP_PROXY_TIMEOUT |
30s |
Maximum time the upstream server has to start sending response headers after the proxy finishes sending the request. Does not cap total upload duration or idle time while reading the response body. Set to 0 to disable. |