Bitcoin Ord indexer: where data synchronization breaks
A Bitcoin Ord indexer turns raw blocks and mempool contents into a clear database: who owns an inscription, how many tokens an address holds, which Runes balances are current. As long as it keeps pace with the chain, it is an invisible layer that the entire product rests on.
The first point of failure is the database lagging behind the chain. A block with dense inscription issuance takes longer to process than the network takes to produce the next one, and the gap accumulates: index synchronization goes first to minutes, then to hours. Data update delay is visible to the user as a stale balance and incorrect transfer status.
The second is divergence from the network during reorganizations. When blocks are replaced, already recorded operations must be rolled back in the same order, otherwise the database retains phantom assets that do not exist on-chain.
Restarting does not fix this: you need a rebuild from a checkpoint and integrity verification by block height.
The third is request failure during activity spikes. A wave of minting a new token hits the same tables, the connection pool runs out, and some requests fail before receiving a response, exactly at the moment of peak load.
The cost is the same in all three cases: the product team handles complaints instead of development, and trust in the data collapses after the first discrepancy. Next we break down how this is addressed.
What deployment in your own environment provides
A full network node and your own index database are two independent layers. The node validates blocks and serves them as they are confirmed; the indexer parses the contents — Ordinals inscriptions, BRC-20 operations, Runes emissions — and writes the result to its own database.
Queries go directly to it, so a lookup by address, collection, or tag responds in fractions of a second regardless of how many clients simultaneously access the same service.
The second effect is independence from other people's limits. Public indexers throttle request rates, return only the tip of history, and change access rules at any moment.
Your own environment keeps the entire depth you specified during initial load and allows reindexing data from the required block height when the parsing schema changes or a new asset type is added.
Recovery fits into minutes, not days: the database is backed up, the node is raised alongside, and the lag is caught up from the network.
Storage is moved to separate read-only replicas — analytical historical queries no longer compete with service requests for the same resources.
And last, the eliminated class of failures due to unreliable data. Your own node validates blocks and correctly handles reorganizations, so output does not diverge from network state.
If lag does appear, it is visible in metrics: block height in the database versus height in the network and the queue of unparsed blocks.
Comparison of options: public explorer, rental, own node
The choice between a public explorer, renting a dedicated node, and your own bitcoin node comes down not to convenience but to indexing limitations.
Public services return data on someone else's schedule: request limits cut off batch queries, history for a specific address arrives incomplete, and response format changes without warning — integration breaks out of nowhere.
Your own node and your own index database remove these limitations but require space for blocks and time for initial synchronization. A hybrid closes the gap: a local cache of hot collections and addresses on top of rental or your own node.
| Option | When it fits | Limitations |
|---|---|---|
| Public explorer | Prototype, one-time check of balances and history | Request limits, incomplete history by address, response format changes without warning |
| Dedicated node rental | You need your own indexing, but do not want to maintain hardware and watch synchronization | Provider dependency, some indexer settings unavailable, subscription-based access |
| Your own bitcoin node + your own index database | Product with constant load and complete data on Ordinals, BRC-20 and Runes | Storage and synchronization on your side, monitoring and on-call needed |
| Hybrid with local cache | High share of repeat requests, response latency matters | Cache must be invalidated on reorgs, logic becomes more complex |
The fork is decided by load and data completeness requirements: a pilot can withstand a public explorer, while a product with history for every address needs only its own node and its own index database.
Implementation stages: from environment audit to handover
Deployment begins not with installing a node but with answers: what volume of history needs to be indexed, do we support BRC-20 and Runes in one environment, and in what time must the indexer respond to a query by address or block number.
This determines the deployment scheme — one node or separation into archive and primary, where the index physically resides, and how access to hot data is organized.
- Infrastructure audit. We look at what is already deployed, whether disk capacity is enough for the full chain history, what network limits exist, and how backup is organized. The result is a list of bottlenecks and resource requirements for the required indexing volume.
- Storage design. We split the index into a hot layer for queries and a cold layer for full history, and define a snapshot retention policy. Then recovery after failure takes minutes, not days.
- Deployment of the node and indexing layer. We raise the node in the required mode, synchronize the chain, and deploy the indexer on top with processing of Ordinals, BRC-20 and Runes. We separately configure reaction to reorganizations so data does not diverge from the chain.
- Access setup. Keys for product services, quotas, request rate limiting, request logging. Read rights and service access are separated.
- Verification on historical data. We run a full reindex and compare control slices: balances, inscription owners, token transfer volumes. A discrepancy in at least one slice is a stop until the cause is determined.
- Handover and team training. We hand over the scheme, update and recovery regulations, and analysis of typical failures. Your engineers perform routine operations themselves and know when to call us.
Delivery package: configurations, schemes, regulations
A deployed node is useless if its logic lives only in the contractor's head. Therefore delivery is closed not by launching a service but by a set of artifacts that your team can use to index, update, and recover the environment without our involvement.
- Indexer configurations — values for each node: reindex depth, write batch sizes, memory limits, rollback thresholds during reorganizations, with comments explaining why exactly this value was chosen.
- Data flow scheme — the path from the network node to storage and data output to external consumers: where information is buffered, at which points loss is possible, how the system survives node lag.
- Access policies and roles — administrative, service, and read-only accounts, keys in the secret store, rotation procedure, and request log.
- Backup scheme — what is included in backups (index state, registry metadata, configurations), at what frequency, what retention depth is, and how the backup is tested for recoverability.
- Update regulations — procedure for rolling out new node and indexer builds, storage schema migrations, rollback points, and conditions under which an update stops.
- On-call regulations — list of metrics and alerts: index lag, block gap, write errors, node unavailability; escalation scheme and planned maintenance windows.
- Recovery documentation — step-by-step raising of the environment from scratch and from backup with control checks of registry integrity after each operation.
We verify the package by running it: we raise the indexer on a clean stand using the same documentation — the regulations must work, not just exist for show.
Case: migration from a public explorer to your own environment
The customer is a marketplace of Ordinals assets, where balances, inscriptions, and BRC-20 / Runes tokens were provided by a public explorer.
Its failures became ours: during issuance peaks, responses arrived with delay, some wallet queries returned stale state, and discrepancies with our own network node reached 0.3% for addresses with active trading.
Support handled complaints about unreliable data manually — this was not a code defect but a lack of control over the data source.
We deployed a network node and our own indexer in the customer's environment: blocks are fetched directly, state is assembled into a relational database with separate tables for inscriptions, token transfers, and Runes operations.
Before writing, the indexer compares block height and hash with the node, and chain reorganizations are rolled back to the last confirmed checkpoint — data does not "drift" when the branch is rebuilt.
What changed in numbers. The share of discrepancies with the network — from 0.3% to zero measurements over a quarter of observations. Full database rebuild time — from 40 hours to 6, which allows the storage schema to be changed calmly.
Recovery after failure — from three hours waiting for someone else's service to 12 minutes: switching to a replica and warming up the index happen automatically. Support requests about unreliable data decreased by an order of magnitude.
The key difference is the class of failures. Previously, failure came from outside and had no clear resolution time. Now it is local, diagnosed from the indexing log, and closed by regulation without loss of confirmed data.
What to do if the indexer is already deployed but diverges from the network?
A discrepancy is almost always localized to a specific layer: mismatch by block height, difference within one block, or parsing error of a specific format — Ordinals, BRC-20, Runes.
We start by polling control heights and hashes from two independent sources: if hashes match, the network is not at fault; the issue is in transaction parsing or storage schema.
Next is verification against the network by checkpoints: we recalculate aggregates (number of inscriptions, token turnover, holder balances) and compare with an independent reference.
A monotonically growing discrepancy indicates a block missed during writing; a jump exactly at one height indicates an unhandled transaction type or incorrect chain rollback.
Partial index rebuild covers most cases: when one format or a narrow height range is lost, we reset records for that range and pass it again without stopping the rest of the index.
A full rebuild with repeated verification is needed if the discrepancy affected several formats, or if we change the storage schema — idempotent writing by the key "height and position in block", transactional batches, and separation of hot and archive data.
Prevention is more reliable than repair: continuous verification against the network by checkpoints shows index desynchronization within minutes.
We put such checks into monitoring with alerts on aggregate deviation, so a chain rollback or format change does not turn into a week-long audit.
Questions about load, integrity, and fault tolerance
The indexer is a derived layer: any state in it is restored by recalculation from blocks and is not considered a source of truth.
Therefore data integrity is checked by comparing the height and hash of the last processed block with the node, and a discrepancy is treated by reprocessing the range. This same property allows rolling indexes back to any saved point without losing accumulated data.
Read and write loads are separated: heavy queries over collections, token balances, and Runes events go to replicas while the main process writes new blocks.
Role-based access restriction — read, write, administration — is set at the query level, not only at the network perimeter.
What happens during a chain reorganization?
A reorganization is tracked by the parent hash of the new block.
If it does not match the last processed one, the indexer cancels records to the depth of the discrepancy and reruns the blocks of the canonical branch — state remains deterministic, not "approximately correct".
What node is needed for operation?
A full node with a complete set of blocks; we keep connection to a trusted provider as a backup channel. The node must serve blocks and transactions without gaps — otherwise recalculation will produce holes and the index will have to be raised from a saved point.
How to update without downtime?
The new version is raised alongside on a separate copy of the index, catches up to the current height, and switches traffic only after checksums are verified. Rollback is returning traffic to the previous version, while the database remains untouched.
Let's discuss the task and return with an estimate and plan
To make the project estimate rely on real loads rather than average numbers, we need a short input from you.
Describe query scenarios, data freshness requirements, and the current environment — this is enough to calculate indexing volumes, choose a node profile, and return with a plan.
- Query scenarios — which lookups the bitcoin ord indexer serves: address balances, BRC-20 history, collection inscriptions, Runes state.
- Freshness requirements — allowable lag from the chain tip, behavior during a reorg, whether block reprocessing is needed.
- Current environment scheme — where the Bitcoin node and storage are located, what accesses exist, whether there is a working indexer to migrate.
- Volumes and parsing depth — from which block to start, whether full inscription history or an observation window is needed.
- Data consumers — who requests the index and how often, in what form the response is needed, what downtime is acceptable.
- Access restrictions — who owns the domain, certificates, and secrets, what access level you are ready to grant the team.
In response, you receive a project estimate by stages, a work plan with dependencies, a deployment scheme, and delivery composition: repository, migrations, configurations, monitoring dashboards, and documentation. Describe the task — we will return with an estimate and plan.







