429 response until the bucket refills — it never queues or delays requests on your behalf. Rate limiting is on by default, applies globally across all API routes, and is one of the most effective guardrails against runaway agent loops eating into your system resources.
Default Rate Limits
These limits apply per API key. A single agent using one key is subject to all three buckets simultaneously.Heap snapshots are the most resource-intensive operation the daemon performs — a full V8 heap snapshot can take up to 47 seconds. The default limit of 2 per minute is intentionally conservative and should rarely need increasing.
When You Are Rate Limited
When a request exceeds your configured limit, the daemon immediately returns an HTTP429 with a Retry-After header telling you how many seconds to wait before retrying:
Handling 429 in the Python SDK
The SDK does not retry automatically — you control the retry logic so your agent’s behavior remains predictable. Here is a simple exponential back-off pattern:Configuring Rate Limits
Set your limits in the[rate_limit] section of axon.toml. All limits are per-API-key.
Environment Variable Equivalents
Every[rate_limit] key maps to an AXON_RATE_LIMIT__* environment variable. Environment variables always take precedence over axon.toml values.
Example — tightening action limits in a CI environment without modifying
axon.toml:
Recommendations
Setaction_per_second conservatively. Action execution touches a live runtime probe, may trigger UI-level effects, and has real-world consequences. A limit of 3–5 is a reasonable starting point for most agents. Reserve higher limits for batch workflows you have explicitly profiled.
Use WebSocket watch instead of polling state. If your agent reacts to state changes, subscribe to the WebSocket stream with GET /substrate/v1/watch instead of polling GET /state on a timer. A WebSocket subscription uses zero rate-limit budget between change events, while a 10 Hz polling loop consumes 10 of your 100 reads-per-second budget every second, even when nothing changes.
Disable rate limiting only in isolated test environments. The rate_limit.enabled = false setting is useful in CI pipelines where you control all traffic, but always run with rate limiting enabled when connected to production applications.
