Coming soon
RPCX: one request instead of a thousand
RPCX is a NoLimitNodes Solana RPC service, coming soon, where you write your own methods in the dashboard. A method can combine node calls with queries over our block and account data, so one request returns the finished answer instead of the thousands of requests it takes today. As far as we know, we are the first Solana RPC provider to offer it.
- Write your own RPC methods in the dashboard
- Combine node calls with queries over our block and account data
- One request returns the finished answer
A wallet’s last 50 transactions
The standard way
51
requests
Each square is one request.
RPCX
1
request
rpcx_walletHistory
How 51 is counted
- getSignaturesForAddress (up to 1,000 a request)1
- getTransaction, one for each50
The list call returns up to 1,000 signatures. A transaction can only be read one request at a time.
Requests your code sends. Counted, not timed. How each is counted is under the figure.
01The problem
RPC was built to answer one small question at a time
That is a fine way to read a balance. It is a poor way to get an answer, and everything that follows from it is a cost your code and your bill carry.
A
One request, one fact.
A balance, a transaction, a block. Each is its own request, and the menu of requests is fixed.
FIG 02One request, one fact B
So every answer is a pile.
A wallet’s history, a pool’s trades, a day of swaps: hundreds, thousands, sometimes hundreds of thousands of requests.
FIG 03A bill for every trip C
So there are limits per second.
Providers count requests per second because requests are the only unit the model gives them to count.
FIG 04A limit on each second D
And you do the joining.
Your code stitches the pieces together, retries the ones that fail, and waits for the slowest.
FIG 05The joining is yours
02The same question
The same question, two ways
A wallet’s last 50 transactions. On the left, what runs today, as real code we ran against a counting server. On the right, the RPCX way, which is illustrative until it ships.
The standard wayRun against a counting server: 51 requests
// wallet_history.mts: a wallet's last N transactions, the standard wayconst RPC = process.env.NLN_RPC_URL! // the RPC endpoint from your dashboardconst KEY = process.env.NLN_API_KEY!const WALLET = process.argv[2]const COUNT = Number(process.argv[3] ?? 50)let requests = 0
async function rpc<T>(method: string, params: unknown[]): Promise<T> { requests++ const res = await fetch(RPC, { method: 'POST', headers: { 'content-type': 'application/json', 'x-api-key': KEY }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }), }) const body = await res.json() if (body.error) throw new Error(`${method}: ${body.error.message}`) return body.result as T}
// one request for the list of signatures...const sigs = await rpc<Array<{ signature: string }>>('getSignaturesForAddress', [WALLET, { limit: COUNT }])
// ...then one request for every transaction in itconst txs = await Promise.all( sigs.map(s => rpc<{ slot: number; meta: { fee: number } }>('getTransaction', [s.signature, { maxSupportedTransactionVersion: 0 }])),)
const fees = txs.reduce((sum, tx) => sum + tx.meta.fee, 0)console.log(`${txs.length} transactions read, ${fees} lamports in fees`)console.log(`${requests} requests`)# wallet_history.py: a wallet's last N transactions, the standard wayimport jsonimport osimport sysimport urllib.requestfrom concurrent.futures import ThreadPoolExecutor
RPC = os.environ["NLN_RPC_URL"] # the RPC endpoint from your dashboardKEY = os.environ["NLN_API_KEY"]WALLET = sys.argv[1]COUNT = int(sys.argv[2]) if len(sys.argv) > 2 else 50requests = 0
def rpc(method, params): global requests requests += 1 request = urllib.request.Request( RPC, data=json.dumps({"jsonrpc": "2.0", "id": 1, "method": method, "params": params}).encode(), headers={"content-type": "application/json", "x-api-key": KEY, "user-agent": "rpcx-example"}, ) with urllib.request.urlopen(request) as response: body = json.load(response) if "error" in body: raise RuntimeError(f"{method}: {body['error']['message']}") return body["result"]
# one request for the list of signatures...sigs = rpc("getSignaturesForAddress", [WALLET, {"limit": COUNT}])
# ...then one request for every transaction in itwith ThreadPoolExecutor(max_workers=16) as pool: txs = list(pool.map(lambda s: rpc("getTransaction", [s["signature"], {"maxSupportedTransactionVersion": 0}]), sigs))
fees = sum(tx["meta"]["fee"] for tx in txs)print(f"{len(txs)} transactions read, {fees} lamports in fees")print(f"{requests} requests")RPCXIllustrative: it does not exist yet
# an illustrative RPCX method; the real syntax ships with the productmethod: walletHistoryparams: [address, count]steps: rows: query: | SELECT signature, slot, block_time, fee, err FROM transactions WHERE has(account_keys, {address}) ORDER BY slot DESC LIMIT {count}return: rows# one request, one answercurl "$NLN_RPC_URL" \ -H "content-type: application/json" \ -H "x-api-key: $NLN_API_KEY" \ -d '{"jsonrpc":"2.0","id":1,"method":"rpcx_walletHistory","params":["YOUR_WALLET_ADDRESS",50]}'- Standard: one request for the list, then one request for every transaction in it. 1 + 50 = 51. The server counted 51 as well.
- RPCX: the method is defined once, in the dashboard. Your code makes one call and gets the finished rows.
- The method syntax and the SQL dialect are not final. The shape of the saving is.
03How a method is made
A method is a small graph
Three kinds of step. Switch them on and off and watch what one request would cost you. Steps that do not depend on each other run side by side.
- Node calls in the method2
- Queries in the method2
- Steps that run side by side4
- Requests you send1
- RPC step
A call to a node, the way you make one today.
- Query step
SQL over our blocks, transactions and accounts. Read-only.
- Transform step
A small expression that joins the results and shapes the one response.
Click a step, or focus it and press Space, to switch it on or off.
04The data
Query the chain, not just the node
A node answers the questions its methods allow. RPCX also lets a method read our block, transaction and account data directly, with SQL. This is the design: the page states no retention window and no speed.
Decoded tables for 37 programs, from 19 projects
transactions
Every transaction: who signed, what it cost, whether it failed.
- signature
- string
- slot
- u64
- block_time
- timestamp
- fee
- u64
- err
- string?
- account_keys
- array
- compute_units
- u64
SELECT signature, slot, feeFROM transactionsWHERE has(account_keys, {wallet})ORDER BY slot DESCLIMIT 3| signature | slot | fee |
|---|---|---|
| 5VERv8…kQ2 | 387040001 | 5000 |
| 3xBnT2…dM9 | 387039988 | 6000 |
| 2LkWq1…aP4 | 387039951 | 5000 |
Values are made up. Table and column names are the design. The decoded tables follow the program schemas in Program Streams.
Program names and logos belong to their owners and are used only to identify the programs RPCX can read. NoLimitNodes is not affiliated with, endorsed by or sponsored by them.
05The dashboard
Write it, test it, publish it
The editor is in your dashboard. Run a method against live data, read the trace of every step, and publish it as a version you can roll back. Everything below is illustrative.
# an illustrative RPCX method; the real syntax ships with the productmethod: walletHistoryparams: [address, count]steps: rows: query: | SELECT signature, slot, block_time, fee, err FROM transactions WHERE has(account_keys, {address}) ORDER BY slot DESC LIMIT {count}return: rows- queryQuery transactions50 rows returned, 1.2M rows scanned
- transformShape the answer50 items
- responseOne responsenewest slot seen: 387,040,001
Cost check before you publish: one query step, no node calls. Illustrative values.
06The requests
Fewer requests to send, to limit, to retry
Every request your code sends is one more to rate-limit, retry and wait for. Set how often you need an answer and see how many requests each way sends.
The task
A wallet’s last 50 transactions
10,000 a day
The standard way
510,000
requests a day
about 5.9 a second, on average
RPCX
10,000
requests a day
about 0.12 a second, on average
51 times fewer requests to send, to limit and to retry.
Requests per second is the average if the day’s requests were spread evenly. Real traffic comes in bursts, so the peak is higher.
A method is metered by the work it does
- Calls to nodes
A method’s RPC steps cost one compute credit per call, the same as a standard call today.
- Data scanned
A method’s query steps cost compute credits by the data they read.
A method is metered by the work it does, in compute credits. Each plan includes a budget of credits every minute, shown next.
07Compute credits
A budget of compute credits every minute
Each plan includes a number of compute credits per minute to spend on methods. A credit measures the work a method does, not how many requests it took to ask.
Pro
12,000
compute credits a minute
200 requests a second, in credits
Ultra
30,000
compute credits a minute
500 requests a second, in credits
Max
60,000
compute credits a minute
1,000 requests a second, in credits
Enterprise
up to6,000,000
compute credits a minute
100,000 requests a second, in credits
How far a minute goes, the standard way
Wallet history: 51 credits the standard way, one for each request.
- Pro235 runs a minute
- Ultra588 runs a minute
- Max1,176 runs a minute
- Enterpriseup to 117,647 runs a minute
A node call: one credit
Each RPC step costs one credit per call, the same as one standard call today.
A query: credits by the data it reads
Query steps cost credits by the data they read. A test run in the dashboard shows the total before you save the method.
A budget every minute
Your plan includes the credits shown above every minute, to spend on any methods you like.
- The numbers follow the request rate each plan already has: one credit is one standard call, so 200 requests a second is 12,000 credits a minute. Enterprise is up to 6,000,000, depending on the methods used.
- The figure under the picker counts node calls only, the standard way. A method’s query steps spend credits on top, by the data they read.
08What changes
What changes
The standard model on the left is how RPC works at any provider. This is a description of the model, not of any company.
| Topic | The standard RPC model | RPCX |
|---|---|---|
| What you can ask | The standard RPC modelThe methods the provider lists | RPCXAny method you write, over node calls and chain data |
| Requests per answer | The standard RPC modelOne per fact: often hundreds or thousands | RPCXOne |
| Where the joining happens | The standard RPC modelIn your code | RPCXOn our side, in the method |
| What limits you | The standard RPC modelRequests per second | RPCXCompute credits per minute, by the work a method does |
| Data you can reach | The standard RPC modelWhat a node exposes through its methods | RPCXBlocks, transactions and accounts, queryable |
As far as we know, RPCX is the first Solana RPC service that lets customers write their own methods over chain data.
09Examples
Six methods, six piles of requests
Each is a real task. The number is what the standard way sends, counted from the list under it. RPCX sends one.
- 01
Wallet summary
SOL, token balances and the last five transactions of one wallet.
8 requests1 request
What the standard way sends
- getBalance1
- getTokenAccountsByOwner1
- getSignaturesForAddress1
- getTransaction5
RPCX:
rpcx_walletSummary - 02
Mint check
The mint, its largest holders and each holder’s account, in one view.
22 requests1 request
What the standard way sends
- getAccountInfo (the mint)1
- getTokenLargestAccounts1
- getAccountInfo (each holder)20
RPCX:
rpcx_mintCheck - 03
Pool snapshot
A pool’s reserves, its price and its last twenty trades.
24 requests1 request
What the standard way sends
- getAccountInfo (the pool)1
- getTokenAccountBalance (two vaults)2
- getSignaturesForAddress1
- getTransaction20
RPCX:
rpcx_poolSnapshot - 04
Portfolio of 500 wallets
Every token position of 500 wallets, valued and totalled.
505 requests1 request
What the standard way sends
- getTokenAccountsByOwner500
- getMultipleAccounts (100 a request)5
RPCX:
rpcx_portfolios - 05
An hour of one pool
Every trade in a pool over an hour, with sizes and wallets.
20,020 requests1 request
What the standard way sends
- getSignaturesForAddress20
- getTransaction20,000
RPCX:
rpcx_poolHour - 06
A day of swaps
Every swap of a token over a day, found by reading every block.
216,000 requests1 request
What the standard way sends
- getBlock (one for each slot)216,000
RPCX:
rpcx_tokenSwaps
10Getting started
From a pile of requests to one, in three steps
- 1
Write the method
In the dashboard, combine node calls, queries and a transform, and name the parameters.
- 2
Test it on live data
Run it, read the trace of every step, and see what it would cost before you publish.
- 3
Call it
Send one request to your usual endpoint with the method name rpcx_ and yours, and read the answer.
RPCX: questions
Not here? Email [email protected] or talk to sales.
What is RPCX?
RPCX is a NoLimitNodes Solana RPC service, coming soon, where you write your own methods in the dashboard. A method combines node calls, SQL queries over our block and account data, and a transform, and returns one finished answer.
Is it still JSON-RPC?
Yes. You call your method through your usual endpoint, as rpcx_ followed by its name, so existing clients and libraries work. What changes is that one request can return an answer that used to take many.
Why does standard RPC need request-per-second limits?
Because it answers one small question per request, a real answer takes many requests, and the number of requests is the only thing a provider can count. RPCX sends one request for the answer, so there are far fewer requests to limit.
Is it faster?
It sends far fewer requests and makes far fewer round trips, and those are counted on this page. We do not publish a time figure here. When RPCX ships we will publish a benchmark you can run yourself.
What can a method read?
Node calls, and our block, transaction and account data through SQL, including decoded tables for the programs in Program Streams. The tables on this page are the design; the data available at launch will be listed in the docs.
What can’t it do?
At first, methods are read-only: they can read the chain but not send transactions. Methods are also limited in how many steps they have and how much they read, so one method cannot run away.
How do compute credits work?
A method is metered by the work it does, in compute credits: one credit for each call it makes to a node, and credits by the data its queries read. Each plan includes a budget of credits every minute, and a test run in the dashboard shows what a method costs before you save it.
How many compute credits does my plan include?
Pro includes 12,000 compute credits a minute, Ultra 30,000 and Max 60,000. Enterprise is up to 6,000,000, depending on the methods used. They follow the request rate each plan already has, at one credit for each standard call.
When can I get RPCX?
RPCX is coming soon. We have not set a date to publish here. Email [email protected] and we will tell you when it opens.
RPCX is coming soon.
Write the method once. Ask for the answer, not the pieces. One request instead of a thousand.
Questions first? Email [email protected] or talk to sales.















