You have a published subgraph. Now an application needs to read it.
What sits between you and an indexer.
You do not query an indexer directly. You query a gateway, which routes your query to an indexer serving that subgraph, handles the payment receipt, and returns the answer.
The gateway is doing real work on your behalf:
- Selection. Choosing among indexers serving that deployment, on price, performance and reliability.
- Payment. Attaching a signed receipt so the indexer can be paid, without you transacting per query.
- Failover. Routing elsewhere when an indexer is slow or wrong.
The consequence worth internalising: you are not talking to one machine. Two identical queries can be served by different indexers. That is the property that makes the data source durable, and it is also the source of the surprises below.
The assumptions to make explicit.
Freshness varies. Indexers are at slightly different chain heights. A query immediately after a transaction may be served by an indexer that has not seen it yet. If your product does read-after-write, handle it explicitly rather than assuming.
Latency is a distribution. Most queries are fast. Some are not, because they went to a different indexer or hit a cold path. Set timeouts and mean them.
The subgraph can fail. A deployment can break on a contract upgrade. Your application should degrade rather than crash, and you should find out from monitoring rather than from users.
Queries cost money. Not much, per query. Enough that an unbounded loop or a runaway client is a bill.
Writing queries that behave.
- Always paginate. An unbounded collection query is slow now and worse later.
- Ask for what you display. Overfetching costs latency and money on every call.
- Do not use the graph as a cache layer. If you need the same answer repeatedly, cache it in your own application.
- Handle the empty case honestly. No results and not indexed yet look identical in the response, and treating an unindexed subgraph as an empty dataset produces a UI that confidently shows nothing.
That last point is worth dwelling on. Absent data rendering as a healthy empty state is one of the most persistent bugs in applications built on indexed data, precisely because nothing errors.
Paying for it.
Query fees are paid in GRT from a balance you top up. Card payment options exist for topping up on Arbitrum, and the payment surfaces change more often than the protocol does, so check the current documentation rather than any article.
Budget by measuring rather than estimating. Instrument query volume per feature in staging and you will find one screen making ten times the calls it needs.
Before reading on: your query returns an empty array. Name three different causes.
The three are indistinguishable in the response, which is the point.
There is genuinely no data. The query is correct, the subgraph is healthy, no entity matches.
The subgraph has not indexed that far yet. Still syncing, or lagging the chain head. The entity exists on chain and not yet in the index.
The subgraph is broken. It failed on a contract upgrade and stopped at some block. Everything after that block is missing and will stay missing.
All three return an empty array with no error. If your application treats empty as “no results”, the third case silently becomes a permanent wrong answer displayed confidently.
The fix is to check indexing status alongside the data: how far has this deployment indexed, and is it healthy. That turns a silent wrong answer into a stale-data warning you can show a user.
Why should the API key never ship in a client application?
Anything in a web or mobile bundle is readable. Proxy through your own backend where the key lives in server configuration and you can rate limit per user.
Two identical queries return slightly different data. Most likely explanation?
The gateway routes across indexers, and they sit at slightly different heights. That variation is the price of not depending on a single machine, and read-after-write needs handling explicitly.
An empty result array can mean no data, still syncing, or a failed deployment. What should an application do?
All three look identical in the response and none of them errors. Absent data rendering as a healthy empty state is one of the most persistent bugs in applications built on indexed data.
0 of 3 answered