> For the complete documentation index, see [llms.txt](https://docs.fast.poker/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fast.poker/for-operators-dealer-service/rpc-governor.md).

# RPC governor

An opt-in throttle that smooths how fast the crank calls its RPC endpoints.

## What it is

The RPC governor is an opt-in, per-channel token-bucket rate limiter plus an in-flight concurrency cap. It is a thin shim wrapped around the crank's RPC connections: one for the L1 base layer and one for the TEE rollup.

It runs on two independent channels: `l1` and `tee`. Each is configured separately.

It is **off by default**. If the config is absent or disabled, nothing is throttled and behavior is unchanged.

## Fail-open

The governor never stalls dealing. If a request would wait longer than the configured `max_wait_ms`, it proceeds anyway rather than dropping the call or blocking it indefinitely.

Correctness always comes from the on-chain program. The governor only shapes request volume. It can throttle traffic, but it can never starve a crank action.

## Per-instance math

The governor is **per-instance, not fleet-wide**. Each crank instance enforces its own limits independently.

If you run a fleet, divide your provider's target RPS by the number of instances when setting `max_rps`. Three instances sharing a 300 RPS budget should each be set to 100.

## Fields

Each channel (`l1` / `tee`) takes:

| Field          | Meaning                                                   |
| -------------- | --------------------------------------------------------- |
| `enabled`      | Throttle this channel (default `false`)                   |
| `max_rps`      | Token-bucket refill rate, requests/sec (`0` = no RPS cap) |
| `max_inflight` | Concurrent in-flight ceiling (`0` = no concurrency cap)   |
| `max_queue`    | Max queued requests before fail-open                      |
| `max_wait_ms`  | Max a request waits before it fail-open proceeds          |
| `ws_exempt`    | Exempt websocket / subscription traffic                   |

One top-level field applies to both channels:

| Field                | Meaning                                                |
| -------------------- | ------------------------------------------------------ |
| `backoff_on_failure` | Back off when a real `429` / rate-limit response lands |

## Environment switch

`CRANK_RPC_GOVERNOR=0` is a panic switch. It disables the governor entirely, regardless of config.

Otherwise the governor config hot-reloads: edits apply on the next sweep with no restart.

## Heartbeat stats

The heartbeat exposes a `governor` object with one entry per channel:

```
governor: { l1: {...}, tee: {...} }
```

Each channel reports:

| Field      | Meaning                            |
| ---------- | ---------------------------------- |
| `enabled`  | Whether this channel is throttling |
| `inflight` | Calls currently in flight          |
| `waiting`  | Calls queued for a slot            |
| `rejected` | Calls that hit the fail-open path  |
| `tokens`   | Tokens left in the bucket          |

The dashboard RPC page surfaces these live.

## When to enable

Turn it on to control RPC cost, or to stop rate-limit (HTTP `429`) cascades from a provider.

Most operators on a paid RPC plan can leave it off.
