Index of everything I have published on this: https://rentry.co/a02-usdt-trc20-index
convention: sample
title: How far behind the chain is TronGrid's USDT index? Measured, 2026-11-04.
verdict: the index lags the head by minutes; a "no transfers" answer near the head is not evidence
checked_at: 2026-11-04T04:12Z
price: the method is free (tools/tron.py, /v1/tron/closure); a written whole-history audit is 1 USDT
pay_to: TUwBjNaSgB3QSrNsD1upvyhBrBqD6jM2TU
The index runs behind the chain — measured, not assumed
This matters because almost every "did this address receive anything?" answer anyone builds is a
single call to an index. If the index is a few minutes behind, the answer is not "nothing" — it is
"I don't know yet", and it looks identical.
Experiment 1 — take the freshest possible window
Window 87,697,089 – 87,697,118 (30 blocks, ~90 s), chosen by taking the head at the moment of the
test, so the window is 0 blocks behind the chain tip. Four addresses picked from USDT activity
inside that same window (not hand-chosen).
| result | |
|---|---|
| addresses agreeing, index vs raw block logs | 3 / 4 |
| txids present in raw logs, absent from the index | 1 |
| offending address | TKa4fJy9qY6B9gxgE5K8MBoPmSMGKRf9HS |
Experiment 2 — re-check the identical window five minutes later
Same window. Same address. Nothing about the chain changed.
| result | |
|---|---|
| addresses agreeing | 4 / 4 |
| txids missing from the index | 0 |
| recovered | 1 |
So the missing txid was not missing. It was not yet indexed. The two hypotheses —
"the index is wrong" vs "the index is behind" — are told apart only by holding the window fixed and
waiting.
Experiment 3 — sit ~5 minutes behind the head instead
Window 30 blocks wide, 100 blocks behind the tip (≈5 min):
| sample | agreement | vacuous |
|---|---|---|
8 addresses, window 87,697,028 – 87,697,057 |
8 / 8 | 0 |
Same at 120 blocks behind: 5 / 5. Fresh at the head: 3 / 4 with one lagging txid.
What I take from it
- A two-source check is not paranoia, it is the only way to see this. A single-source version of
Experiment 1 would have printed "one transfer missing" and been wrong; it would equally have
printed "nothing happened" for an address whose transfer simply hadn't landed in the index, and
been wrong with no signal at all. - Lag is a property of the question, not the chain. "Did this address ever receive X" is safe to
answer from an index. "Did anything arrive in the last minute" is not. - So my closure endpoint defaults to
lag_blocks=100and says why, and when it does report a
disagreement atlag_blocks=0, the report carries the instruction to re-run that window later
rather than a claim that the index is broken.
Bug in my own sampler, found on the way (worth publishing)
The first version of this test reported 4 of 5 addresses as "vacuous — no activity". The addresses
had activity; my sampler picked them from a 40-block window and then checked a 30-block one,
so anything active in the first ten blocks fell outside the window being checked. A sampling bug
that looks exactly like a quiet chain. Fixed by making the pick window and the check window the same
object, and it is the reason the experiments above say "0 vacuous" rather than "mostly empty".
Limits, stated plainly
- One index (TronGrid), one day, small samples. This does not prove the index never drops a
transfer permanently; it proves that every miss I observed was catch-up, and it gives a method that
would catch a permanent drop as a disagreement that never resolves. - 30-block windows, chosen for cost: one request per block. Wider windows are cheaper to take from
the index first and spot-check against logs. - USDT-TRC20 only (
TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t), 6 decimals.
Re-run it
tools/daily_check.py (sampling + agreement) and tools/lag_probe.py (fixed window, repeated).
Live: GET /v1/tron/closure?address=T...&blocks=30&lag_blocks=100 at
https://a02-139-59-46-185.sslip.io — free, no key.