Logo
New RPC users get 35% off their first monthView the offer
OnFinality Learn
Infrastructure & Operations14 min read

Reading Sui System State over RPC: Epoch, Validators, Checkpoints

A practical guide to reading Sui's protocol-level system state over JSON-RPC for epoch tracking, validator monitoring, and checkpoint reconciliation.

TL;DR

Sui exposes protocol-level system state through JSON-RPC methods such as suix_getLatestSuiSystemState and sui_getLatestCheckpointSequenceNumber. These reads return the current epoch, its start timestamp and duration, the protocol version, the reference gas price, and the active validator set with stake and voting power. Operators and indexers use them for health checks, lag detection, and checkpoint reconciliation. This article explains the epoch model, the request envelope, payload reduction strategies, and a runnable Node.js example. It also provides a reproducible results table and troubleshooting guidance for common issues.

User State Versus System State in Sui RPC

Sui's JSON-RPC surface splits into two broad categories: user state and system state. User state covers objects, coins, transactions, and events—the data that applications and end users interact with directly. System state covers protocol-level parameters: the current epoch, the validator committee, staking pools, the reference gas price, and the protocol version. These are not user-owned objects; they describe the network's operational context.

The distinction matters because the two categories have different read patterns and costs. User-state reads are typically point lookups or paginated queries scoped to an address or object ID. System-state reads, by contrast, return a single large object that includes the full validator set. That payload is heavier and changes less frequently, so caching and summary fields become important.

For operators and indexers, system state is the authoritative source for health checks and reconciliation. If your indexer records transactions without recording the epoch in which they occurred, you cannot later reconcile your data against committee rotations or gas price changes. The Sui RPC guide covers the broader method surface, while this article focuses specifically on the system-state read path.

  • User state: objects, coins, transactions, events—scoped to addresses or IDs.
  • System state: epoch, committee, stake, gas price, protocol version—network-wide.
  • System-state reads are heavier and should be cached or summarized where possible.

The Sui Epoch Model and Why It Matters for Long-Running Jobs

Sui advances in epochs, which are bounded periods defined by a start timestamp and a duration. At each epoch boundary, the validator committee can rotate, staking rewards are distributed, and the reference gas price can change. The Sui epoch concepts documentation describes how epoch duration is set and how committee rotation works.

For any long-running job—an indexer, a monitoring agent, or a reconciliation script—the epoch is a critical piece of metadata. If you record a transaction's effects without recording the epoch, you lose the ability to correlate that data with the committee that processed it or the gas price that was in effect. This is especially important for financial applications that need to audit stake changes or gas costs over time.

The epoch start timestamp and duration are returned as epochStartTimestampMs and epochDurationMs in the system state object. These fields let you compute the remaining time in the current epoch, which is useful for scheduling maintenance or anticipating committee changes. However, these timestamps are generated by the node and can be subject to clock skew relative to your client.

  • Epochs bound committee rotation, staking rewards, and gas price changes.
  • Record the epoch alongside any indexed data for later reconciliation.
  • epochStartTimestampMs and epochDurationMs allow computing remaining epoch time.

Reading System State with suix_getLatestSuiSystemState

The method suix_getLatestSuiSystemState returns the latest SUI system state object. According to the Sui JSON-RPC API reference, this object includes the current epoch, epochStartTimestampMs, epochDurationMs, safeMode, protocolVersion, referenceGasPrice, and the active validator set. Each validator entry includes fields such as name, stakingPoolId, votingPower, stake, and gasPrice.

This is the primary method for reading protocol-level state. It is a single call that returns a large payload, so it should not be polled at high frequency. For monitoring, a cadence of once per epoch or once per few minutes is usually sufficient. The Sui validator and staking concepts explain how voting power and staking pools relate to the committee.

Because the validator list is large, some providers offer summary fields or alternative methods that return a trimmed view. The availability of these optimizations is documented per provider and varies. Where supported, prefer a summary read for light monitoring and reserve the full system state for reconciliation or detailed analysis.

  • Returns epoch, timestamps, protocol version, gas price, and validator set.
  • Validator entries include name, stakingPoolId, votingPower, stake, and gasPrice.
  • Payload is heavy; avoid high-frequency polling and prefer summary fields where available.

Lightweight Liveness with sui_getLatestCheckpointSequenceNumber

The method sui_getLatestCheckpointSequenceNumber returns just the latest certified checkpoint sequence number. This is a cheap call compared to fetching the full system state. It is useful as a liveness probe: if the sequence number is advancing, the node is producing or receiving checkpoints. If it stalls, the node may be behind or disconnected.

Combining this method with system state gives you a lag signal. The system state tells you the network's current epoch and committee; the checkpoint sequence number tells you how far the node's checkpoint tip has advanced. If you compare the node's tip against a reference tip from another endpoint, you can detect a node that is behind the network.

For a deeper treatment of checkpoint consumption, see the checkpoint stream and ledger service article. That piece covers streaming checkpoints, while this article focuses on the sequence number as a lightweight probe.

  • Returns only the latest certified checkpoint sequence number—cheap and fast.
  • Use as a liveness probe and for lag detection against a reference tip.
  • Pair with system state to correlate checkpoint progress with epoch boundaries.

The JSON-RPC Request Envelope and Cost Considerations

All Sui JSON-RPC calls use the standard JSON-RPC 2.0 envelope: a jsonrpc field set to "2.0", an id for request correlation, a method string, and a params array or object. The JSON-RPC 2.0 specification defines this structure. Sui's methods follow this convention, with method names like suix_getLatestSuiSystemState and sui_getLatestCheckpointSequenceNumber.

The cost caveat is that system-state reads are heavier than point reads. A call to suix_getLatestSuiSystemState returns the full validator set, which can be hundreds of entries. This consumes more bandwidth and processing time than a simple object lookup. For high-frequency monitoring, use sui_getLatestCheckpointSequenceNumber instead, or check whether your provider offers a summary method.

When building a monitoring loop, separate the cadences: poll the checkpoint sequence number frequently for liveness, and fetch the full system state less often for epoch and committee data. This reduces load on both your client and the node.

  • Envelope: jsonrpc, id, method, params—per JSON-RPC 2.0.
  • System-state reads are heavier than point reads; adjust polling cadence accordingly.
  • Use checkpoint sequence for frequent liveness; system state for periodic reconciliation.

Runnable Node.js Example: Fetching and Summarizing System State

The following example uses the @mysten/sui client to fetch the latest system state and checkpoint sequence number, compute the remaining time in the current epoch, and print a compact health summary. It assumes you have a Sui RPC endpoint URL. Replace the placeholder with your provider's endpoint.

The script prints epoch, epochStartTimestampMs, epochDurationMs, protocolVersion, referenceGasPrice, and the active validator count. It then fetches the latest checkpoint sequence number and computes the remaining epoch time in milliseconds. Finally, it prints a one-line health summary.

This example is intentionally minimal. In production, you would add error handling, retries, and possibly a comparison against a reference endpoint for lag detection.

import { SuiClient } from '@mysten/sui/client';

const client = new SuiClient({ url: 'https://your-sui-rpc-endpoint.example' });

async function main() {
  const systemState = await client.getLatestSuiSystemState();
  const epoch = systemState.epoch;
  const epochStart = Number(systemState.epochStartTimestampMs);
  const epochDuration = Number(systemState.epochDurationMs);
  const protocolVersion = systemState.protocolVersion;
  const referenceGasPrice = systemState.referenceGasPrice;
  const activeValidators = systemState.activeValidators.length;

  const checkpointSeq = await client.getLatestCheckpointSequenceNumber();

  const now = Date.now();
  const elapsed = now - epochStart;
  const remaining = Math.max(0, epochDuration - elapsed);

  console.log('Epoch:', epoch);
  console.log('Epoch start (ms):', epochStart);
  console.log('Epoch duration (ms):', epochDuration);
  console.log('Protocol version:', protocolVersion);
  console.log('Reference gas price:', referenceGasPrice);
  console.log('Active validators:', activeValidators);
  console.log('Latest checkpoint seq:', checkpointSeq);
  console.log('Remaining epoch time (ms):', remaining);
  console.log('Health: epoch', epoch, '| validators', activeValidators, '| checkpoint', checkpointSeq, '| remaining', remaining, 'ms');
}

main().catch(console.error);

Raw JSON-RPC Example with curl

If you prefer not to use the SDK, you can call the methods directly with curl. The following example sends a JSON-RPC request for the latest system state and extracts the epoch and validator count using jq. Replace the endpoint URL with your provider's.

This approach is useful for quick checks or for integrating into shell scripts. Note that the response is large; piping through jq to extract only the fields you need reduces noise.

For the checkpoint sequence number, a separate call is shown. You can combine both calls in a script to compute lag or remaining epoch time.

curl -s -X POST https://your-sui-rpc-endpoint.example \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"suix_getLatestSuiSystemState","params":[]}' \
  | jq '{epoch: .result.epoch, protocolVersion: .result.protocolVersion, referenceGasPrice: .result.referenceGasPrice, validatorCount: (.result.activeValidators | length)}'

curl -s -X POST https://your-sui-rpc-endpoint.example \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"sui_getLatestCheckpointSequenceNumber","params":[]}' \
  | jq '{latestCheckpointSeq: .result}'

Reproducible Results Table for Your Endpoint

To measure your own endpoint's behavior, fill in the following table. Run the Node.js or curl example against your endpoint and record the values. Repeat at different times to observe epoch changes and checkpoint progression.

The table columns capture the key fields: endpoint, epoch, protocolVersion, referenceGasPrice, active validator count, latest checkpoint sequence number, node tip sequence number (if you have a reference), and a lag signal. The lag signal can be computed as the difference between your node's checkpoint sequence and a reference tip from another endpoint.

This table is a template. The values you record are your own measurements; they are not provided here. Use it to build a baseline and detect anomalies over time.

  • Endpoint: the RPC URL you are testing.
  • Epoch: the current epoch number from system state.
  • ProtocolVersion: the protocol version reported by the node.
  • ReferenceGasPrice: the current reference gas price.
  • ActiveValidatorCount: number of active validators in the committee.
  • LatestCheckpointSeq: the node's latest certified checkpoint sequence number.
  • NodeTipSeq: a reference tip from another endpoint (if available).
  • LagSignal: NodeTipSeq minus LatestCheckpointSeq (positive means your node is behind).

Limitations and Tradeoffs in System-State Reads

The validator list is large and can be trimmed. Some providers offer summary fields or alternative methods that return a reduced view. The availability of these optimizations is documented per provider and varies. If your provider does not support them, you must fetch the full payload and extract what you need.

Epoch timing fields are informative but subject to clock skew between the node and your client. The epochStartTimestampMs is generated by the node; if your client's clock differs, the computed remaining time may be off. Treat it as an estimate, not a precise countdown.

safeMode and protocolVersion can change at an upgrade. A node in safe mode may halt certain operations, and the protocol version increments with network upgrades. Your monitoring should treat these as dynamic fields and alert on unexpected changes. Method availability is also documented per provider and varies; not all endpoints expose every method.

  • Validator list is heavy; summary fields are provider-dependent.
  • Epoch timestamps are subject to clock skew; treat remaining time as an estimate.
  • safeMode and protocolVersion can change at upgrades; monitor for unexpected values.
  • Method availability varies by provider; verify before relying on a method.

Troubleshooting Common System-State RPC Issues

Method not found: If suix_getLatestSuiSystemState or sui_getLatestCheckpointSequenceNumber returns a method-not-found error, the endpoint may not support that method. Check your provider's documentation. Some providers expose only a subset of the Sui JSON-RPC surface.

Heavy payload: If the response is slow or times out, the full validator list may be too large for your client or network. Try a summary method if available, or increase your timeout and reduce polling frequency. For liveness, use sui_getLatestCheckpointSequenceNumber instead.

Epoch confusion: If the epoch number seems inconsistent with your expectations, verify that you are querying the correct network (mainnet vs testnet). Also check whether the node is in safe mode or behind. The epoch advances at boundaries; if you poll frequently, you may see it change mid-loop. Record the epoch with each data point to avoid mixing data from different epochs.

  • Method not found: verify provider support for the method.
  • Heavy payload: use summary fields or switch to checkpoint sequence for liveness.
  • Epoch confusion: confirm network, check safe mode, and record epoch with data.

Next Steps for Monitoring and Reconciliation

To build a robust monitoring setup, combine system-state reads with checkpoint sequence probes. Use the Sui network page to find endpoints, and consider the API service for managed access. For pricing and rate limits, see RPC pricing.

For deeper dives into related topics, explore the OnFinality Learn hub. The article on queryTransactionBlocks cursor pagination covers transaction pagination, while reading Sui coin balances and metadata covers user-state reads. For object versioning, see Sui object versions and Lamport ordering.

Finally, integrate epoch tracking into your indexer or monitoring agent. Record the epoch alongside every data point, and alert on epoch changes, safe mode, or protocol version changes. This ensures your data remains reconcilable across committee rotations and gas price updates.

  • Combine system-state reads with checkpoint sequence probes for lag detection.
  • Record epoch with every data point for reconciliation.
  • Alert on epoch changes, safe mode, and protocol version changes.

Never Worry about Infrastructure Again

OnFinality takes away the heavy lifting of DevOps so you can build smarter and faster.

Get Started