The Lodestar Oracle
gateway_id: lodestarno API keyAn independent QoS oracle for The Graph, built on active probing rather than gateway telemetry. Every number below was measured here. It is served in the QoS oracle's own schema (gateway_id is on every data point because the format was built for several gateways), so an existing consumer query works against it unchanged, with no API key and nobody's gateway in the read path.
There is no canonical QoS oracle. There is this one and there is Edge & Node's, and they are not the same instrument: theirs counts what their gateway actually routed: real traffic, real fees, real demand, while this one probes deliberately and can tell you whether a response was correct, which no traffic census can. Lodestar mirrored and served their feed until 2026-08-05 and has stopped. Their numbers are still read here for one purpose: comparing ours against a second opinion, below.
What this oracle cannot produce: query volume, fees, or any measure of demand. Probes are not traffic. Where a figure is unmeasured this page says so rather than showing a comfortable zero.
Edge & Node oracle
Lodestar Oracle
Allocations measured
Divergent responsesCorrectness needs two or more indexers answering the identical probe, and until direct paid dispatch we could not choose who answered. Nothing has been checked yet: this is "not established", not "all clean".
Indexer quality, scored on Lodestar's measurements
Composite of four things we measure ourselves: correctness (0.40), availability (0.30), freshness (0.20) and coverage (0.10). No sub-score, verdict or alert reads anyone else's feed, so a stall upstream leaves every number here untouched.
Only indexers Lodestar has actually probed appear. That is the whole list: roughly a third of the active set, not all of it. An indexer missing from this table has not been judged and found wanting; it has not been judged.
A fifth component, query volume, was removed rather than left at zero. Volume is demand, a fact about which indexers a gateway chose to route to, and no amount of probing reproduces it. Scoring operators on a number we cannot measure, from a feed that had been stale for a month, was rewarding and punishing them for our blind spot.
A dash means that component had nothing to score, never that it scored zero. Freshness is dashed most often: it now comes only from chainhead lag we measured ourselves, where it used to fall back to the oracle's figure, which reads as pristine and was last written on 1 July.
A probe count in amber is under 50. The grade is computed the same way, but a sorted table makes an A off four probes look like an A off six hundred, and it is not the same claim.
Lodestar's own measurements, worst first
Agreement with Edge & Node's oracle
If our numbers disagreed wildly with the oracle's, that would need explaining before anyone relied on this feed. So here is the check, run over the same trailing window the oracle's figures cover, on the 0 allocations both feeds cover.
Methodology, including what we can't tell you
How the numbers are made
- We send GraphQL probes pinned to a specific block hash at chainhead − 12, so every indexer is asked the identical question about identical state.
- Responses are canonicalised with JCS (RFC 8785), hashed with SHA-256 and clustered. An indexer in the minority cluster returned confident, well-formed wrong data, the signal a 200-counting oracle cannot produce.
- Success rate counts HTTP 200s with no transport or GraphQL error. Latency covers successful probes only, because a fast 500 is not fast service and the failure is already counted once.
- Freshness is chainhead lag: the indexer's own reported head compared against chainhead at probe time, which we resolve ourselves rather than taking on trust. Clamped at zero, and conservative by a few seconds of block production, so it will not resolve a lag of tens of blocks on a sub-second chain, but an indexer hundreds or thousands of blocks behind measures cleanly.
- Measurements land in 5-minute buckets and are recomputed over a trailing window every minute, so a restart or a late arrival converges instead of leaving a hole.
Where this differs from Edge & Node's oracle
- Probes, not traffic. Our
query_countis how often we asked, not how popular an indexer is. Never read it as demand. - One vantage point. One location, a fixed query set, no real user load. The oracle's census of live traffic is better at "what did users actually experience"; ours is better at "is this indexer serving correct, fresh data right now".
- How to read our success rate. Unknown until the feed reports its dispatch mix; treat the success rate as an upper bound. Where the two feeds overlap our success rate has come out higher than Edge & Node's, never lower, which is what selection bias looks like from the inside.
- Which fields are unaffected. Correctness is the genuinely independent one: responses are compared against each other, so nothing an indexer asserts about itself can move it. Blocks-behind is partly independent: we resolve chainhead ourselves, but the indexer's position is taken from its own
_meta, so an operator misreporting its head would appear current. Success rate is the weakest of the three, for the selection-bias reason above. - Correctness is currently thin. Judging a response requires at least two indexers answering the identical probe, and gateway dispatch seldom provides that corroboration, so most rows read
—, meaning not established rather than clean. An earlier version scored a "minority of one" as wrong and briefly accused a named indexer on a sample where nothing had been compared; requiring a real majority fixed that and revealed how sparse the coverage actually is. Direct dispatch fixes the coverage. - Percentiles only at bucket resolution. Percentiles don't recombine, so we publish p50/p95/p99 per 5-minute bucket and refuse to invent a daily figure.
- Nulls mean not measured. Correctness is null when nothing was comparable, never 100%. The per-bucket fee fields are null permanently, not pending: probes are now TAP-paid, but what we spend is not what an indexer earns. Realised earnings come from Arbitrum settlement, above.
What no feed of ours can ever tell you
- How many queries Edge & Node's gateway sent other indexers. That is their gateway's private log.
- Why that gateway chose not to route to you. The selection reasoning is internal to it, and no amount of probing recovers a counterfactual.
- Your own traffic from that gateway, though that one isn't a mystery: it is in your
indexer-servicelogs and your TAP receipts already.
Why this exists
On 2026-07-29 Edge & Node's oracle stopped publishing for over 35 hours. The relayer was fine (funded, no failed transactions, no stuck nonce), so nothing on-chain revealed it, and every consumer kept serving stale numbers that looked current, this dashboard included.
Watching for that turned up something larger. Since 2026-07-01 the oracle's main subgraph deployment (Dtr9r…) has rejected every message the publisher sends, with "… is not a valid submitter". The publisher moved to a signer its allowlist does not carry, all while sitting at chain tip reporting no indexing errors. The posts keep arriving and none become data. Anyone querying that deployment has received 1 July figures ever since, with nothing in the response to say so.
The data itself was never lost, and it is worth being precise about that. The publisher is live (you can watch it post to Gnosis at the top of this page) and a community fork of the subgraph (CnfJ5…, maintained by ellipfra) carries an updated allowlist and has indexed every message throughout. It is current to today. So the oracle is not down; one deployment of its subgraph is, and the consumers pointed at that deployment cannot tell.
Which is the sharper version of the same problem. A stalled feed that announces itself is an outage. A stalled feed that answers every query with month-old numbers, at chain tip, with no indexing errors, while a working copy of the same data sits one subgraph id away, is a correctness failure that no amount of uptime monitoring finds.
Hence the ages on the front of this page, and hence the parts below that say "not measured" rather than showing a comfortable zero.
And hence, since 2026-08-05, no mirror. Lodestar held a copy of Edge & Node's published history and served it, which sounded like resilience and was really a second way to hand people stale numbers with our name on them. Two oracles measuring the network independently is worth more than one oracle and a photocopy.
Using the feed
GraphQL: a drop-in for the oracle subgraph
The endpoint reuses the QoS oracle's entities and field names, including allocationDailyDataPoints, indexer(id:), subgraphDeployment(id:) and queryDailyDataPoints, with the same where filters (dayNumber, dayNumber_gte, query_count_gte, id_gt) and orderBy/orderDirection. BigInt and BigDecimal serialise as strings exactly as graph-node does. No API key.
POST https://www.lodestar-dashboard.com/api/foghorn/qos/graphql# Your existing QoS oracle query, unchanged.
# Only the endpoint differs.
{
indexer(id: "0xyour-address") {
allocationDailyDataPoints(first: 100) {
subgraph_deployment_ipfs_hash
proportion_indexer_200_responses
avg_indexer_latency_ms
avg_indexer_blocks_behind
correctness_rate # Lodestar addition: was the data RIGHT?
}
}
}Additive fields only, so adopting it breaks nothing: correctness_rate, comparable_count, divergent_count, and _foghornStatus for feed age.
REST, if you'd rather not speak GraphQL
GET /api/foghorn/qos/statusAge of both feeds. The one endpoint worth alerting on.
GET /api/foghorn/qos/buckets?indexer=0x…&hours=245-minute resolution, including latency percentiles. Optional deployment= filter.
GET /api/foghorn/qos/compare?days=3Per-allocation agreement with Edge & Node's oracle, plus its blind spots.
GET /api/foghorn/indexer/0x…/allocations-qosBoth sources side by side for one indexer, each labelled with its provenance.
Field mapping
What each field means on the Lodestar Oracle. Edge & Node's feed uses the same names for different things, most importantly query_count, so a consumer switching between the two must reread this table, not assume it.
| Oracle field | What ours means |
|---|---|
| query_count | Lodestar Oracle: probes we dispatched, never a measure of demand. Edge & Node: real queries their gateway routed. |
| proportion_indexer_200_responses | Share of probes answered 200 with no transport or GraphQL error. |
| avg_indexer_latency_ms | Mean over successful probes only, weighted by successes when rolled up to a day. |
| avg_indexer_blocks_behind | The indexer's reported head against chainhead at probe time. We resolve the reference; the position is their claim, so an indexer misreporting its head would read as fresh. |
| avg_query_fee / total_query_fees | Always null, and staying that way. This field means fee-per-query within a bucket, and our buckets count probes rather than demand — so any number here would describe our own spending, not what an indexer earned. Realised earnings are served separately, from Arbitrum settlement, in the section above. |
| correctness_rate | A Lodestar addition that no traffic census can produce. Share of comparable responses matching the stake-weighted majority. Null when nothing was comparable; never read null as 100%. |
| gateway_id | "lodestar" on every row. The oracle format carries this so several gateways can publish. |