Indexing Best Practices
Windows & Limits
Sei inherits Tendermint finality (single block confirmation) but enforces RPC limits to protect full nodes. Respect the following caps when building log indexers:
eth_getLogs
window default: 2,000 blocks.- Open-ended queries (no
fromBlock
/toBlock
) cap at 10,000 logs; always anchor both block bounds. - Subscription catch-up delivers up to 512 events per batch before backpressure kicks in.
- Archive providers may expose wider windows; detect and adapt via feature flags.
Backfill Strategy
- Backfill newest → oldest to keep current data fresh while draining history.
- Use chunk sizes of 250–500 blocks to balance node load and throughput.
- Persist checkpoints after each successful window to resume without duplicate ingestion.
- When replaying synthetic events, record the
synthetic
log flag (v6.1.11+ ) to differentiate from contract-emitted logs.
Reorg Handling
Sei produces instant finality; however, nodes may restart mid-ingest. Implement safeguards anyway:
- Persist the highest fully processed height; after restarts resume from
height - safetyBuffer
(recommend 10 blocks). - Verify block hash continuity even under finality to detect provider restarts.
- For websocket subscribers, rehydrate missed blocks using
eth_getLogs
if the connection drops for more than 3 seconds.
Rate Limits & Retries
- Throttle requests to one window per 200 ms unless working with a dedicated archive endpoint.
- Respect HTTP
429
responses—exponential backoff starting at 1s, max 30s. - Retry
EOF
and transient network errors up to 5 attempts; avoid retrying contract-level reverts. - Encode idempotency by hashing blockNumber + logIndex to prevent duplicate writes when retries occur.
Schema Design
- Model logs with composite unique key
(blockNumber, transactionHash, logIndex)
. - Store
topics
as arrays with a secondary index ontopic0
for fast event filtering. - Persist
synthetic
boolean to separate Cosmos module events from contract logs. - Keep raw
data
hex for replay; additionally decode known ABI payloads into typed columns for analytics surfaces.
Flow At A Glance
01
Discover latest height
Call eth_blockNumber
every loop and persist the safe tip before starting a window.
02
Windowed eth_getLogs
Query bounded ranges (≤2k blocks) and honour the log cap. Store the synthetic
flag with each event.
03
Write & checkpoint
Commit the batch, advance the checkpoint (height
, txHash
, logIndex
), then throttle before the next loop.
Reference Implementations
@sei-js/evm indexing scripts
Production-ready ingestion loop with retries, checkpointing, and synthetic log metadata.
Tracing playbook
Understand trace limits and panic handling when debugging ingestion anomalies.
Pointers deep dive
Learn how pointer metadata influences synthetic events surfaced during indexing.
Last updated on