The gateway now ships in the
praisonai-bot package. praisonai serve gateway still works exactly as documented here; for a standalone install see praisonai-bot Migration.For the composed one-switch experience, see Reliability Preset. This page documents the drain-only knob.
drain_timeout.
Quick Start
1
Enable via the CLI flag
2
Enable via YAML config
3
Enable via Python
4
Override drain timeout at stop time
You can also pass a one-off timeout when stopping programmatically:
5
Enable via GatewayConfig (Python-first)
Set
drain_timeout on GatewayConfig directly — no CLI flag and no YAML key required. This closes the CLI + YAML + Python parity gap for embedders wiring up a gateway from Python.drain_timeout must be >= 0 (ValueError otherwise); 0/None disables the drain window.6
Bound a wedged teardown with a diagnostic deadline
stop() also accepts a grace budget — extra seconds beyond drain_timeout before the shutdown-phase deadline watchdog fires a diagnosable self-exit if teardown itself is wedged (adapter disconnect(), WS drain, ledger/DB close). Requires the loop watchdog to be configured; a no-op otherwise.How It Works
The drain phase usesDrainTimeoutPolicy from praisonaiagents.gateway.protocols. If the timeout elapses before all turns finish, the process exits forcefully but still attempts to flush any queued outbound messages.
Behaviour Table
Configuration Precedence
When multiple sources specifydrain_timeout, the most specific wins:
The
GatewayConfig(drain_timeout=…) field is consulted only when there is no CLI flag and no YAML key. The start_with_config fallback checks "drain_timeout" not in gw_cfg before reading the field, so an explicit drain_timeout: null in YAML wins over the field.
When drain_timeout is 0, the gateway exits immediately on SIGTERM without draining. When drain_timeout is None (and no reliability preset is set), a 5-second drain window is applied by the default posture — use reliability="off" to restore immediate-teardown behaviour.
Want to turn on graceful drain with a single switch alongside inbound admission control? See Gateway Reliability Presets.
Best Practices
Set drain_timeout in Kubernetes or container deployments
Set drain_timeout in Kubernetes or container deployments
Container orchestrators send SIGTERM before force-killing a pod. Set This gives the gateway 50 seconds to finish turns and 10 seconds of buffer for the process to exit cleanly.
drain_timeout to slightly less than the terminationGracePeriodSeconds in your pod spec:Keep the timeout proportional to your P99 turn latency
Keep the timeout proportional to your P99 turn latency
If your agent typically responds in 5 seconds and your P99 is 20 seconds, set
drain_timeout: 25. A timeout much larger than your P99 adds unnecessary shutdown delay without benefit.Cross-link with gateway-scale-to-zero
Cross-link with gateway-scale-to-zero
Graceful drain is especially important for scale-to-zero deployments. Combine it with the existing scale-to-zero feature to ensure scale-down events don’t interrupt active users.
Pair drain_timeout with the shutdown-phase deadline
Pair drain_timeout with the shutdown-phase deadline
drain_timeout bounds how long the gateway waits for in-flight turns; it does not bound how long a wedged teardown step (adapter disconnect(), WebSocket drain, ledger/DB close) can hang after the wait window ends. For that, enable the loop watchdog and set gateway.watchdog.shutdown_grace (or pass grace=… to stop()) — a wedged teardown then self-exits with an all-thread stack dump and exit code 75 at drain_timeout + shutdown_grace, instead of sitting silent until systemd’s TimeoutStopSec reaches SIGKILL. Added in PR #5084 / issue #5079. See Loop Watchdog → Shutdown-phase deadline mode.Related
Gateway Scale to Zero
Scale the gateway down when idle and back up on demand
Gateway Drain Trigger
Port-less external drain signal for hosted deployments
Detect a wedged loop and bound a wedged shutdown with a diagnostic self-exit.
The front-rung sibling — bound a wedged pre-loop startup with the same diagnostic self-exit.

