Chain status
Each chain has one status value. It describes Farbeam's ability to read the chain, measured by this service. It is not a statement about the chain itself. A chain can be healthy while the RPC providers are not answering, and Farbeam reports degraded or down in that case.
#The rule
The state is computed each time you ask for it, in this order. poll is the chain's poll_seconds.
| Order | State | Condition |
|---|---|---|
| 1 | starting | No poll has completed since the process started |
| 2 | down | Seconds since last_ok is greater than max(poll * 6, 180) |
| 3 | degraded | consecutive_failures is 2 or more, or lag_seconds is greater than max(poll * 3, 90) |
| 4 | ok | None of the above |
With the current poll intervals, the max always gives the same numbers.
| Chain | poll_seconds | down after | degraded when lag exceeds |
|---|---|---|---|
| Ethereum | 12 | 180 s | 90 s |
| Base | 16 | 180 s | 90 s |
| BNB Chain | 16 | 180 s | 90 s |
| Arbitrum One | 16 | 180 s | 90 s |
| OP Mainnet | 30 | 180 s | 90 s |
| Polygon PoS | 30 | 180 s | 90 s |
| Solana | 30 | 180 s | 90 s |
#The fields behind the state
{
"chain": "ethereum",
"name": "Ethereum",
"kind": "evm",
"head": 26343493,
"head_time": "2026-11-04T19:18:23.000Z",
"lag_seconds": 6.4,
"rpc_latency_ms": 602,
"last_ok": "2026-11-04T19:18:29.782Z",
"consecutive_failures": 0,
"last_error": null,
"indexed_since_start": 353,
"status": "ok",
"head_age_seconds": 15
}This object is cut to the status fields. It was captured from GET /status on 2026-11-04 UTC.
| Field | Meaning |
|---|---|
lag_seconds | Age of the head block when it was read. It is not refreshed between polls. |
head_age_seconds | Age of the head block at response time. It grows between polls, so 15 seconds is normal on a 12 second poll. |
last_ok | Time the last poll finished without error |
consecutive_failures | Polls that threw an error since the last good one |
scan_lag_blocks | Blocks between the head and the log cursor, on the four EVM chains with an index. Absent elsewhere. |
last_error | upstream failed when a source failed, poll failed for any other error |
#What each state means for you
| State | Stored data | New data | What to do |
|---|---|---|---|
ok | Readable | Arriving | Nothing |
starting | Readable | Not yet | Wait. This follows a restart and normally lasts for one poll. |
degraded | Readable | May be late or partial | Treat recent gaps as possibly incomplete |
down | Readable | Not arriving | Do not read silence as a quiet chain. Rows for this period will not be filled in later. |
The log cursor catches up after a short outage. A down period longer than 2,000 blocks leaves a permanent gap, and so does a restart, because the cursor is held in memory. See indexing.
#Edge cases
- **A fresh head with
degraded.** The head is read beforeeth_getLogs. If the log call fails, the head still moves, but the poll counts as a failure. Two in a row givedegradedeven thoughlag_secondsis small. It means rows may be late. - **
okis not "complete".** An indexed chain can readokwhilescan_lag_blocksis above 0, and Solana readsokwhile sampling. The state speaks to the poller, not to coverage. - Chains with no index. OP Mainnet and Polygon have a status too.
indexed_since_startstays at 0 by design. - **
/healthis narrower.** Service health returnsstatus: "ok"whenever the process can answer, pluschains_okandchains_total. Usechains_okfor a quick check, and use Status for detail.
#History
The service stores one sample per chain per 5 minute bucket for 30 days. Each sample holds the state at the moment of writing, lag_seconds and latency_ms. Read them with Status history, or see them on the status page. hours accepts 1 to 720.
Samples show measured state. They do not make up a published uptime figure, and Farbeam has no SLA. An SLA is Planned. measuring_since on /status gives the time of the first stored sample, so you can see how short the record is.
#Sources
GET /status also returns latest_event (the newest stored row per chain), watch_list (the Solana exchange watch list), and keyed_rpc_daily_limit_reached. It returns one row for each outbound source: name, ok, calls, failures, latency_ms, last_ok, last_error_at and error. The counters reset on restart, and a source appears only after its first call. ok reflects the last call only. See data sources for the list.
To build your own monitor, follow the status monitoring recipe.