Sui RPC latency is dominated by geographic distance, shared vs dedicated infrastructure, and the API protocol (JSON-RPC vs gRPC vs GraphQL). Sui's ~400ms finality sets a practical response budget. This article provides a reproducible measurement script, optimization guidance (prefer gRPC, use multiGet, paginate), and distinguishes documented claims from independent benchmarks.
Direct Answer: What Determines Sui RPC Latency?
Sui RPC latency is the time between sending a request and receiving a response, and it is dominated by three factors: geographic distance to the endpoint, whether the endpoint is shared or dedicated, and—critically—the API protocol you use. Legacy JSON-RPC over HTTP is the slowest, while Sui's native gRPC and GraphQL interfaces can cut latency significantly for the same query. Sui's ~400ms finality means that for most read operations, the network itself is not the bottleneck; the RPC layer is. To optimize, prefer gRPC where supported, use multiGet endpoints to batch queries, and paginate efficiently.
This article explains the mechanisms behind Sui RPC latency, provides a reproducible measurement script you can run against any endpoint, and gives concrete optimization strategies. We separate documented protocol behavior from independent benchmarks and from your own measurements, so you can make informed decisions without relying on vendor claims.
Sui's Architecture and Its Impact on RPC Latency
Sui is a delegated proof-of-stake blockchain with a novel object-centric data model. Transactions are processed in parallel, and finality is achieved in about 400ms (as documented in Sui's official docs). This means that when you query the chain for a transaction's effects, the data is available almost immediately after submission. However, the RPC layer can add significant latency depending on how you access that data.
Sui exposes three primary API surfaces: JSON-RPC (HTTP), gRPC, and GraphQL. JSON-RPC is the legacy interface, widely supported but verbose and inefficient for complex queries. gRPC uses HTTP/2 and binary serialization (protobuf), reducing payload size and connection overhead. GraphQL allows you to request exactly the fields you need, avoiding over-fetching. For latency-sensitive applications, gRPC is generally the fastest, followed by GraphQL, with JSON-RPC being the slowest.
The heaviest query patterns are those that fetch large amounts of data, such as queryTransactionBlocks with many filters, or loops that call getTransactionBlock for each transaction ID. These patterns amplify latency because each request incurs network round-trip time and server-side processing. Sui's multiGet endpoints (e.g., multiGetCoins, multiGetTransactionBlocks) are designed to batch these queries into a single request, dramatically reducing latency.
- Sui finality: ~400ms (documented by Sui docs).
- API protocols: JSON-RPC (HTTP/1.1), gRPC (HTTP/2), GraphQL.
- Heavy patterns:
queryTransactionBlocks, loops of singlegetcalls. - Batching:
multiGetCoins,multiGetTransactionBlocksreduce round-trips.
Measuring Sui RPC Latency: A Reproducible Script
To measure latency accurately, you need a script that sends controlled requests and records response times. Below is a Node.js script that measures three types of calls: a simple queryChainIdentifier (lightweight), getTotalTransactionBlocks (medium), and multiGetCoins (heavier). It also measures a gRPC call if you have the @mysten/sui.js client with gRPC enabled (note: gRPC support varies by provider; check your endpoint's capabilities).
Run this script against your endpoint of choice. Record the results in the table provided. This is a method for you to verify performance, not a vendor benchmark. Endpoint location, network conditions, and server load will cause variation.
// save as measure-sui-latency.js
// Run: node measure-sui-latency.js <RPC_URL> [--grpc]
const https = require('https');
const url = process.argv[2] || 'https://fullnode.mainnet.sui.io';
const useGrpc = process.argv.includes('--grpc');
function jsonRpcCall(method, params) {
return new Promise((resolve, reject) => {
const body = JSON.stringify({ jsonrpc: '2.0', id: 1, method, params });
const start = Date.now();
const req = https.request(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
}, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => {
const latency = Date.now() - start;
resolve({ status: res.statusCode, latency, data: JSON.parse(data) });
});
});
req.on('error', reject);
req.write(body);
req.end();
});
}
async function measureGrpc() {
// Requires @mysten/sui.js and a gRPC-compatible endpoint
const { SuiClient, getFullnodeUrl } = require('@mysten/sui.js/client');
const client = new SuiClient({ url, transport: 'grpc' });
const start = Date.now();
await client.getChainIdentifier();
return Date.now() - start;
}
(async () => {
console.log(`Endpoint: ${url}`);
console.log('Running 5 iterations each...\n');
const results = {};
// JSON-RPC measurements
for (const [name, method, params] of [
['queryChainIdentifier', 'sui_getChainIdentifier', []],
['getTotalTransactionBlocks', 'sui_getTotalTransactionBlocks', []],
['multiGetCoins', 'sui_multiGetCoins', ['0x0000000000000000000000000000000000000000000000000000000000000000', null, 10]]
]) {
const latencies = [];
for (let i = 0; i < 5; i++) {
const res = await jsonRpcCall(method, params);
latencies.push(res.latency);
}
results[name] = latencies;
console.log(`${name}: avg ${(latencies.reduce((a,b)=>a+b)/latencies.length).toFixed(0)}ms, min ${Math.min(...latencies)}ms, max ${Math.max(...latencies)}ms`);
}
if (useGrpc) {
const latencies = [];
for (let i = 0; i < 5; i++) {
latencies.push(await measureGrpc());
}
results['gRPC queryChainIdentifier'] = latencies;
console.log(`gRPC queryChainIdentifier: avg ${(latencies.reduce((a,b)=>a+b)/latencies.length).toFixed(0)}ms, min ${Math.min(...latencies)}ms, max ${Math.max(...latencies)}ms`);
}
console.log('\nResults table (fill in your own):');
console.log('| Call | Avg (ms) | Min (ms) | Max (ms) |');
console.log('|------|----------|----------|----------|');
for (const [name, lats] of Object.entries(results)) {
console.log(`| ${name} | ${(lats.reduce((a,b)=>a+b)/lats.length).toFixed(0)} | ${Math.min(...lats)} | ${Math.max(...lats)} |`);
}
})();Interpreting Your Results: What to Expect
The script outputs average, min, and max latencies for each call. Here's how to interpret them:
A queryChainIdentifier call should be the fastest, often under 100ms on a well-connected endpoint. getTotalTransactionBlocks may be slightly slower because it requires server-side aggregation. multiGetCoins with a large limit can be significantly slower if the server has to fetch many coin objects. If you see latencies above 500ms consistently, your endpoint may be overloaded or geographically distant.
Sui's ~400ms finality means that for transaction status checks, a response time of 400ms or less is acceptable. For read-heavy applications, aim for p95 latency under 200ms for simple queries. If your measurements exceed these thresholds, consider the optimizations in the next section.
- Expected ranges (documented / varies by provider): simple queries <100ms, medium <200ms, heavy <500ms on dedicated endpoints.
- If p95 > 500ms, investigate endpoint load or network path.
- Compare JSON-RPC vs gRPC: gRPC often 20-50% lower latency for the same query (documented by Sui docs and independent benchmarks).
Optimizing Sui RPC Query Speed
Once you have baseline measurements, apply these optimizations to reduce latency:
- Prefer gRPC over JSON-RPC: gRPC uses HTTP/2 and binary serialization, reducing overhead. Many providers support gRPC on the same endpoint (e.g.,
https://fullnode.mainnet.sui.iowith gRPC port 443). Check your provider's documentation.
- Use multiGet endpoints: Instead of looping over
getCoinorgetTransactionBlock, usemultiGetCoinsormultiGetTransactionBlocksto batch requests. This reduces round-trips from N to 1.
- Pagination strategy: Use vertical pagination (limit/offset) for small datasets, but for large datasets, use horizontal pagination (cursor-based) to avoid deep offsets that cause server-side scanning. Sui's
queryTransactionBlockssupports cursor-based pagination.
- Cache responses: For data that doesn't change frequently (e.g., chain identifier, total transaction blocks), cache at the client or proxy level. Use HTTP caching headers if available.
- Use subscriptions: For real-time updates, use WebSocket subscriptions instead of polling. This reduces latency for event-driven applications.
- Choose a dedicated endpoint: Shared endpoints are subject to noisy neighbors. A dedicated endpoint (e.g., via OnFinality's API service) provides consistent performance.
Common Failures and Fixes
When measuring or optimizing Sui RPC latency, you may encounter these issues:
- Timeouts: If your requests time out, increase the timeout in your client. Sui's JSON-RPC can be slow for heavy queries; consider using gRPC which has better streaming.
- Rate limiting: Many providers enforce rate limits. If you hit 429 errors, implement exponential backoff or use a provider with higher limits (see Sui RPC rate limits and compute units).
- gRPC not supported: Not all endpoints support gRPC. Check the provider's docs or use a service like OnFinality's API service that offers both.
- Incorrect pagination: Using
limitandoffseton large datasets can cause slow responses. Switch to cursor-based pagination usingnextCursor.
- Network congestion: If you're in a different region than the endpoint, latency increases. Use a provider with global edge caching or deploy your own node in a region close to your users.
Tradeoffs and Limitations
While gRPC is faster, it requires a client that supports protobuf, which may add complexity. GraphQL is flexible but can be slower than gRPC if you over-fetch. JSON-RPC is universally supported but verbose.
Caching can introduce stale data; use appropriate TTLs. Subscriptions maintain persistent connections, which may increase resource usage.
Independent benchmarks (e.g., comparenodes) show that provider performance varies widely. Always measure your own workload. Sui's official docs provide performance characteristics, but real-world latency depends on your specific use case and network conditions.
Next Steps: Further Reading and Tools
Now that you understand Sui RPC latency, explore these resources to deepen your knowledge:
- Sui network overview - Learn about Sui's architecture and endpoints.
- Sui RPC guidance (RPC Assistant) - Get specific recommendations for Sui RPC usage.
- Sui RPC rate limits and compute units - Understand how rate limits affect latency.
- OnFinality Learn hub - More tutorials and guides.
- RPC pricing - Compare dedicated vs shared endpoint costs.
- API service - Explore OnFinality's managed RPC endpoints.