Skip to main content
Each data point in the protocol has exactly one canonical source. Duplicating reads across both the subgraph and RPC creates consistency issues and wasted bandwidth. This guide defines which source to use for each category of data.

Decision Rule

Subgraph for data that is historical, paginated, aggregated, or spans multiple contracts. RPC for data that must reflect the latest block, powers transaction pre-validation, or represents authoritative onchain state.

Subgraph Data

Use GraphQL queries against the subgraph for:
Data CategoryExamplesWhy Subgraph
Position historyClosed positions, PnL history, liquidation recordsUnbounded growth, needs pagination and filtering
Activity feedsPoolTransaction timeline, VaultEvent historyAppend-only logs across multiple contracts
AnalyticsDailyStats aggregates, fee breakdowns, volumePre-aggregated by the indexer
Cross-contract joinsPosition with its Account, reductions with parent positionSingle query spans what would require multiple RPC calls
Oracle historyForward round history, fixing price archiveTime-series data for charts
Protocol audit trailModeTransition history, fee event recordsImmutable event log

Latency

The subgraph indexes events as blocks are confirmed. On Sepolia, expect 1-2 block latency (12-24 seconds). Polling the subgraph at a 15-second interval (the default in the UI) covers most use cases.

RPC Data

Use direct contract reads (useReadContract, publicClient.readContract) for:
Data CategoryContractFunctionsWhy RPC
Current pricesOracleModulegetForwardPrice, getForwardPrices change every publisher update; subgraph may lag
Position PnLPositionManagerunrealizedPnl, positionEquity, isLiquidatableComputed from latest forward price, not stored onchain
Account stateMarginAccountsavailableBalance, collateralBalance, imLockedTotalAuthoritative balance for transaction pre-validation
Pool metricsPoolVaultpoolEquity, utilization, maxWithdrawableDerived from current totalAssets and live exposure
Config valuesConfigimFactorBps, tradingFeeBps, minPositionNotionalSource of truth for form validation and fee estimates
Risk capsRiskManagermaxPositionNotional, maxAccountNotional, maxNetExposureComputed from live pool equity
Protocol modeModeControllercurrentMode, canOpenPositionMust be authoritative for button enable/disable states
Open position IDsPositionManagergetOpenPositions, allOpenPositionIdsAuthoritative set for the current block

Anti-Patterns

Never Use getContractEvents

All event-based data comes from the subgraph. Scanning events via RPC (getContractEvents, getLogs with fromBlock: "earliest") scans the entire chain and times out on testnets.

Never Duplicate Sources

If position history comes from the subgraph, do not also fetch closed positions via RPC. If the current mode comes from RPC, do not also query ProtocolState from the subgraph for the same purpose.

Never Use Subgraph for Pre-Validation

Transaction forms (open position, deposit, withdraw) must validate against RPC reads. A subgraph value that is 15 seconds stale could allow a transaction that immediately reverts.

Hybrid Pattern

Some UI views combine both sources. The pattern is: subgraph for the list, RPC for live-updating fields on each item. Example: Open positions table
  1. Query open position IDs from the subgraph (paginated, with entryStrike, notional, fixingTimestamp)
  2. For each visible position, read unrealizedPnl and positionEquity from PositionManager via RPC
  3. Refresh subgraph data every 15 seconds, RPC data every block
This gives you efficient pagination from the subgraph and real-time PnL from RPC without duplicating the source of truth for either.

Source Assignment Summary

Data PointSourceRationale
Position list (open)SubgraphPaginated, filterable
Position list (closed)SubgraphHistorical, unbounded
Unrealized PnLRPCComputed from live price
Account collateral balanceRPCAuthoritative for tx validation
Account position countSubgraphAggregated
Pool total assetsRPCChanges every block
Pool share price (live)RPCDerived from live total assets
Pool share price (historical)SubgraphStored per-event in PoolState
Fee totalsSubgraphPre-aggregated
Forward price (current)RPCMust be fresh for trading
Forward price (history)SubgraphTime-series for charts
Fixing pricesSubgraphHistorical archive
Daily volumeSubgraphPre-aggregated in DailyStats
Operating modeRPCAuthoritative for UI state
Mode historySubgraphAudit trail

Subgraph Overview

Endpoint URLs and indexed data sources.

Query Examples

Ready-to-use GraphQL patterns.

TypeScript SDK

SDK setup for RPC reads via wagmi.