TL;DR
- Your Triton bill is based on bandwidth and, for services such as standard RPC, requests; this post is about bandwidth
- gRPC streaming (Dragon's Mouth, Fumarole, Riptide) is billed on the compressed bytes we send you, so turning on zstd lowers your bill but will increase your latency.
- HTTP JSON-RPC is billed on the uncompressed size of the response, whether or not you ask for gzip; gzip still makes responses faster to download, but it doesn't change what you pay
- WebSocket traffic isn't compressed, so you're billed on the bytes we send
- The most effective way to cut JSON-RPC bandwidth is to ask for less data: slice and filter account reads, request compressed account data, and move polling loops to streams
- Below, we go through each service with the settings that make the biggest difference
Which gigabytes count
We built our pricing to be easy to read: you pay per GB of bandwidth, plus per million requests on services such as standard RPC, at the rates on our pricing page, as we set out in The end of the black box: Triton's new RPC pricing.
But "per GB" leaves one question open. Many responses are compressed on their way to you, so which gigabytes do we count?
Some of our customers asked exactly that.
Here's the full answer, service by service, along with what you can do to reduce what you pay.
The short answer
Why gRPC and JSON-RPC are billed differently
The difference comes from where compression happens.
For gRPC streams, compression happens at the source. The streaming server compresses each message before it leaves, so the bytes we measure are already compressed. What we send is what we bill.
For JSON-RPC, the node builds a full, uncompressed response. Our load balancer then gzips it on the way out if your client asks for it. We bill on the data generated at the origin, the full response the node produced, because that reflects the resources it took to serve your request. Compressing at the load balancer saves time on the wire, but it doesn't change the work done inside our platform.
In practice, gzip cuts large, structured JSON responses, such as full blocks, to a third of their size or less in transit, so it's still worth keeping on for speed. It just doesn't reduce your bandwidth charge.
Service-by-service guidance
gRPC streaming: Dragon's Mouth, Fumarole and Riptide
Billed on: compressed bytes sent.
Enable zstd if your round-trip time to the endpoint is above about 8 ms, and almost always above 30 ms. It cuts the bytes we send you, which lowers your bill and helps you keep up with the chain during traffic spikes. Full-block and full-chain subscriptions send the most data, so they save the most. Compression uses CPU on both ends and adds latency, so test it on your workload.
- In Rust (yellowstone-grpc-client), add .accept_compressed(CompressionEncoding::Zstd) to your GeyserGrpcClient builder
- With our test client, pass --compression zstd
- In TypeScript, @triton-one/yellowstone-grpc 5.0.1 and later (the Rust-backed NAPI client) supports zstd: pass grpcDefaultCompressionAlgorithm: 1 in the channel options (0 is gzip). Earlier versions were built on @grpc/grpc-js, which has no zstd, so upgrade if you're still on one
- Python's grpcio doesn't support zstd; use gzip, which our gRPC servers also accept
Then cut what you receive:
- Account include and required filters keep only the programs you care about
- Subscribe to the data you use: if you only need transactions for a handful of programs, a transaction subscription costs far less than full blocks
HTTP JSON-RPC
Billed on: uncompressed response size, regardless of the Accept-Encoding header.
Keep gzip on, since it speeds up large responses. Then make the responses smaller at the source:
How much base64+zstd saves depends on the data. For the biggest cut, combine it with dataSlice and filters. In an internal test in March 2024, one getProgramAccounts call returned every USDC token account:
A compressed, sliced account read looks like this:
{
"jsonrpc": "2.0",
"id": 1,
"method": "getAccountInfo",
"params": [
"<address>",
{
"encoding": "base64+zstd",
"dataSlice": { "offset": 0, "length": 165 }
}
]
}WebSocket (Whirligig)
Billed on: bytes sent. WebSocket traffic isn't compressed, so the bytes sent and the uncompressed size are the same.
Subscribe to the specific accounts and programs you need rather than broad program subscriptions, and use dataSlice and base64+zstd encoding on accountSubscribe and programSubscribe. Whirligig applies dataSlice to these notifications; standard Solana nodes ignore it there and send the whole account. For high-volume feeds, Dragon's Mouth gRPC with zstd will cost less.
Where Triton stands
- We bill on two things you can measure yourself: requests and bytes. No compute units, no conversion tables.
- We want you to pay for what you need, not for what you don't. Several of the tips above reduce what we bill you, and we're recommending them anyway.
- If your bandwidth usage looks higher than you expect, tell us and we'll go through the numbers with you.
FAQ
Do you bill for compressed or uncompressed bandwidth?
We bill for compressed bandwidth for gRPC streaming. For other RPC calls we track and bill the uncompressed bandwidth.
Does sending Accept-Encoding: gzip lower my bill?
No. gzip is applied by our load balancer after the response is built, and we bill on the response size before compression. It still makes large responses arrive faster, so keep it on.
Is zstd or gzip better for gRPC streams?
zstd, if your round-trip time to the endpoint is above about 8 ms, and almost always above 30 ms. Like any compression, it uses CPU on both ends and adds latency, so test it on your workload. Our servers also accept gzip, so use that if your client can't do zstd, for example Python's grpcio.
Does this apply to Superbank (historical data) and Cloudbreak (getProgramAccounts)?
Yes. Superbank and Cloudbreak queries are standard JSON-RPC calls, so they're billed on uncompressed response size. Their rates are on the pricing page. Requesting base64+zstd encoding with dataSlice and filters on getProgramAccounts is the most direct way to shrink those responses.
Where can I see my bandwidth usage?
Open the Billing tab in your customer dashboard at customers.triton.one. The Product Breakdown table shows your requests and bandwidth for each product, so you can see what drives your bill.