Three posts on what a subgraph actually is, what it cost us to run our own graph-node, and the snapshot-first indexer we replaced it with.
Series3 parts
Stackgraph-node → TypeScript + Prisma
ChainBNB Chain
The whole series, in one picture
RECOVERING "CURRENT STATE" AFTER AN OUTAGE
graph-node replay
~102,000,000 blocks replayed from block 8,738,570
snapshot indexer
~5 batched Multicall3 requests, current state only
Same question — “what's staked right now?” — two very different bills.
This is the entire argument of the series: graph-node can only recover by re-deriving history event by event. A snapshot just asks the chain what's true right now.
01. What Is a Subgraph, and How Did Our Staking Backend Actually Work?
Before we talk about why we changed it, here’s what it actually was
If you’ve ever opened a DeFi or GameFi dashboard and seen “Total Staked,” “Your Rewards,” or a list of every stake you’ve ever made, you’ve seen the output of an indexer. This post is the first in a three-part series about how FaraLand’s staking backend evolved — starting with what it actually was, before we get into why we changed it.
The problem indexers solve
A blockchain node is great at answering one kind of question: “what is the state of the world right now, or at block N?” It is terrible at answering questions like:
- “Give me every wallet that has ever staked into this contract.”
- “What’s the total amount currently staked, broken down by pool?”
- “Show me this user’s full staking history, sorted by date.”
None of that is stored anywhere as a queryable object. It’s scattered across thousands or millions of individual transaction logs. Answering those questions by talking directly to an RPC node means re-scanning the chain’s history yourself, every time — slow and expensive for anything beyond a toy query.
An indexer's job is to watch the chain, turn raw events into structured records, and let you query those records instantly instead of re-deriving them from logs every time.
Enter The Graph

The Graph is the most widely used framework for building exactly this kind of indexer for EVM chains, and it’s what Faraland’s staking system was built on.
From the moment it’s deployed, graph-node replays the chain from ourconfigured startBlock, executes our WASM handlers against every matching event in order, and persists the resulting entities. Once it catches up to the chain head, it keeps listening for new blocks and applies the same handlers as new events arrive.
What our staking subgraph actually watched
Concretely, Faraland’s staking subgraph tracked five separate staking contracts on BNB Chain as it evolved over time — an original OldStaking contract, and two generations of dedicated single-asset and LP staking pools (V2 and V3):
- OldStakingblock: 8,738,570
- SingleV2block: 15,886,200
- LPV2block: 15,886,190
- SingleV3block: 31,048,737
- LPV3block: 31,048,744
Each of those contracts emits Staked, Unstaked, and (for the newer ones) EmergencyWithdrawn events. The mapping handlers turned those into a small graph of entities: a Knight (the staked hero NFT), a User (the staker), a UserStake (the specific hero–user pairing), and Stake/UnStake transaction records — five contracts’ worth of raw events, continuously reduced down into “who has how much staked, on which hero, in which pool.”
One detail worth calling out, because it matters later: the LP pools apply a weight multiplier to how much they contribute to a user’s aggregate totalStaked field, while the single-asset pools don’t. That’s not a bug — it’s an intentional design decision baked directly into the mapping logic, and any faithful reimplementation has to preserve it exactly, quirks and all.
How it was actually deployed
Faraland didn’t use The Graph’s hosted service or the decentralized network. Every subgraph — staking included — was deployed to a graph-node instance FaraLand ran itself:
That’s a self-hosted graph-node and a self-hosted IPFS node (subgraph manifests and WASM builds are distributed via IPFS), both operated and paid for by the team, continuously, for as long as the staking page needed to keep working, and therefore it costs costs a lot of money
That setup did the job for a long time. But running our own piece of The Graph’s indexing stack — instead of just running our own five contracts’ worth of event handlers — comes with a very different cost and operational profile than it might first appear. That’s where Part 2 picks up.
**Disclaimer: Digital asset prices are subject to high market risk and price volatility. $FARA token and NFT are designed solely for use within our on-chain gaming ecosystem and is intended exclusively for participation in gameplay experiences. They are not, and should not be considered as, an investment vehicle, security, financial instrument, or speculative asset. Holders should have no expectation of profit, return on investment, or appreciation in value from the purchase, holding, or use of this token and NFT.
