Skip to content

Production Checklist

Before exposing a Thunder instance to production traffic, walk through every item below. Each entry links to the relevant documentation section for details.


The admin listener exposes function deployment, configuration, and lifecycle endpoints. Always require authentication.

Terminal window
thunder --api-key "$(openssl rand -hex 32)"

Without --api-key, the admin API is open to any client that can reach the admin port.

Serve HTTPS on the ingress and admin listeners. See TLS Configuration for flag details.

Terminal window
thunder \
--tls-cert /etc/thunder/ingress.crt --tls-key /etc/thunder/ingress.key \
--admin-tls-cert /etc/thunder/admin.crt --admin-tls-key /etc/thunder/admin.key

SSRF protection is enabled by default. Verify that it has not been explicitly disabled. When enabled, outbound fetch() calls to private/internal IP ranges (RFC 1918, loopback, link-local) are blocked.

Terminal window
# Do NOT set this in production
# --disable-ssrf-protection

If specific internal endpoints must be reachable, use --allow-private-net <cidr> to allowlist them explicitly.

For supply-chain integrity, require that deployed bundles are signed with a trusted key.

Terminal window
thunder \
--require-bundle-signature \
--bundle-public-key-path /etc/thunder/bundle-signing.pub

Set request and response body limits appropriate for your workloads.

Terminal window
thunder \
--max-request-body-size 5242880 \
--max-response-body-size 10485760

See Resource Limits for defaults and behaviour.

Cap concurrent connections and optionally enable rate limiting.

Terminal window
thunder \
--max-connections 10000 \
--rate-limit 5000

7. Set appropriate isolate resource limits

Section titled “7. Set appropriate isolate resource limits”

Tune heap, CPU time, and wall-clock limits for your function workloads.

Terminal window
thunder \
--max-heap-mib 128 \
--cpu-time-limit-ms 50000 \
--wall-clock-timeout-ms 60000

Conservative defaults are provided, but production workloads may require adjustment. See Resource Limits for guidance.


Thunder handles function execution. Place a reverse proxy (nginx, Envoy, Caddy) in front for:

  • Subdomain-based routing to different function endpoints.
  • External TLS termination if preferred.
  • Request filtering and WAF integration.
  • Load balancing across multiple Thunder instances.

Example nginx upstream:

upstream thunder {
server 127.0.0.1:9000;
}
server {
listen 443 ssl;
server_name *.functions.example.com;
location / {
proxy_pass http://thunder;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

Enable OTEL export for traces, metrics, and logs.

Terminal window
thunder \
--otel-enabled \
--otel-endpoint "http://otel-collector:4317" \
--otel-service-name "thunder-prod" \
--otel-protocol grpc

See Environment Variables for the full list of OTEL settings.

Point your load balancer or orchestrator health checks at the internal health endpoint:

GET /_internal/health

This endpoint returns 200 OK when the server is ready to accept requests. Use it for:

  • Kubernetes livenessProbe and readinessProbe.
  • Load balancer health checks.
  • Monitoring and alerting.

When the process receives SIGTERM, Thunder stops accepting new connections and drains in-flight requests. Set a timeout that matches your orchestrator’s termination grace period.

Terminal window
thunder --graceful-shutdown-timeout-ms 30000

Ensure the orchestrator’s grace period is longer than this value to avoid forced kills during drain.

The isolate pool determines how many isolates are kept warm and how quickly cold starts are absorbed. Tune for your traffic profile.

Terminal window
thunder \
--pool-enabled \
--pool-global-max-isolates 256 \
--pool-min-free-memory-mib 512

See Scaling for autoscaling signals and pool configuration.


ItemFlag / ConfigDefaultAction
Admin API key--api-keyNone (open)Set a strong random key.
Ingress TLS--tls-cert, --tls-keyDisabledProvide cert and key.
Admin TLS--admin-tls-cert, --admin-tls-keyDisabledProvide cert and key.
Request body limit--max-request-body-size5 MiBReview for your workloads.
Response body limit--max-response-body-size10 MiBReview for your workloads.
Max connections--max-connections10000Tune for expected concurrency.
Heap limit--max-heap-mib128 MiBIncrease for memory-heavy functions.
CPU time limit--cpu-time-limit-ms50000 msAdjust for CPU-heavy functions.
Wall-clock timeout--wall-clock-timeout-ms60000 msMatch expected latency budgets.
SSRF protectionEnabled by defaultOnDo not disable.
Bundle signing--require-bundle-signatureOffEnable for supply-chain security.
OTEL--otel-enabledOffEnable for production observability.
Health check/_internal/healthAlways availableConfigure in load balancer.
Graceful shutdown--graceful-shutdown-timeout-msMatch orchestrator grace period.
Isolate pool--pool-global-max-isolates256Tune for traffic volume.