> ## Documentation Index
> Fetch the complete documentation index at: https://docs.goldsky.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How Boost routes requests

> Learn which JSON-RPC requests Boost can serve, which calls always forward, and how mixed batches are handled.

export const BoostDiagram = () => <div style={{
  border: '1px solid var(--gsk-hair, rgba(17,24,39,0.12))',
  borderRadius: 14,
  padding: 16,
  margin: '20px 0',
  background: 'var(--gsk-panel, #fcfcfb)'
}}>
    <style>{`
      .boost-diagram-mobile { display: none; }
      @media (max-width: 640px) {
        .boost-diagram-desktop { display: none; }
        .boost-diagram-mobile { display: block; }
      }
    `}</style>

    <svg className="boost-diagram-desktop" viewBox="0 0 760 250" role="img" aria-labelledby="boost-flow-title boost-flow-description" style={{
  width: '100%',
  height: 'auto'
}}>
      <title id="boost-flow-title">How Boost routes JSON-RPC requests</title>
      <desc id="boost-flow-description">
        Requests travel from your application to Boost. Eligible historical and tip-of-chain reads are answered from Goldsky indexed data. Other calls are forwarded to your RPC provider.
      </desc>
      <defs>
        <marker id="boost-arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto">
          <path d="M 0 1 L 9 5 L 0 9 z" fill="var(--gsk-wire, #94a3b8)" />
        </marker>
        <marker id="boost-arrow-accent" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto">
          <path d="M 0 1 L 9 5 L 0 9 z" fill="var(--gsk-purple, #7c3aed)" />
        </marker>
      </defs>

      <rect x="24" y="96" width="160" height="58" rx="12" fill="var(--gsk-card, #fff)" stroke="var(--gsk-hair, rgba(17,24,39,0.12))" />
      <text x="104" y="131" textAnchor="middle" fontSize="16" fontWeight="600" fill="var(--gsk-ink, #111827)">Your app</text>

      <path d="M 184 125 L 280 125" fill="none" stroke="var(--gsk-purple, #7c3aed)" strokeWidth="1.6" markerEnd="url(#boost-arrow-accent)" />
      <text x="232" y="113" textAnchor="middle" fontSize="11" fontWeight="500" fill="var(--gsk-purple, #7c3aed)">JSON-RPC</text>

      <rect x="288" y="96" width="174" height="58" rx="12" fill="var(--gsk-purple, #7c3aed)" />
      <text x="375" y="131" textAnchor="middle" fontSize="17" fontWeight="650" fill="var(--gsk-on-accent, #fff)">Boost</text>

      <path d="M 462 112 C 520 98, 526 57, 580 57" fill="none" stroke="var(--gsk-wire, #94a3b8)" strokeWidth="1.5" markerEnd="url(#boost-arrow)" />
      <text x="520" y="75" textAnchor="middle" fontSize="11" fontWeight="500" fill="var(--gsk-sub, #6b7280)">eligible read</text>
      <rect x="586" y="26" width="150" height="62" rx="12" fill="var(--gsk-card, #fff)" stroke="var(--gsk-gold, #d97706)" />
      <text x="661" y="53" textAnchor="middle" fontSize="15" fontWeight="600" fill="var(--gsk-gold, #d97706)">Goldsky data</text>
      <text x="661" y="71" textAnchor="middle" fontSize="11" fill="var(--gsk-sub, #6b7280)">served by Boost</text>

      <path d="M 462 138 C 520 152, 526 193, 580 193" fill="none" stroke="var(--gsk-wire, #94a3b8)" strokeWidth="1.5" markerEnd="url(#boost-arrow)" />
      <text x="520" y="181" textAnchor="middle" fontSize="11" fontWeight="500" fill="var(--gsk-sub, #6b7280)">everything else</text>
      <rect x="586" y="162" width="150" height="62" rx="12" fill="var(--gsk-card, #fff)" stroke="var(--gsk-gray, #6b7280)" />
      <text x="661" y="189" textAnchor="middle" fontSize="15" fontWeight="600" fill="var(--gsk-ink, #111827)">Your provider</text>
      <text x="661" y="207" textAnchor="middle" fontSize="11" fill="var(--gsk-sub, #6b7280)">forwarded by Boost</text>
    </svg>

    <svg className="boost-diagram-mobile" viewBox="0 0 340 430" role="img" aria-labelledby="boost-flow-mobile-title boost-flow-mobile-description" style={{
  width: '100%',
  height: 'auto'
}}>
      <title id="boost-flow-mobile-title">How Boost routes JSON-RPC requests</title>
      <desc id="boost-flow-mobile-description">
        Requests travel from your application to Boost. Eligible historical and tip-of-chain reads are answered from Goldsky indexed data. Other calls are forwarded to your RPC provider.
      </desc>
      <defs>
        <marker id="boost-arrow-mobile" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto">
          <path d="M 0 1 L 9 5 L 0 9 z" fill="var(--gsk-wire, #94a3b8)" />
        </marker>
        <marker id="boost-arrow-mobile-accent" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto">
          <path d="M 0 1 L 9 5 L 0 9 z" fill="var(--gsk-purple, #7c3aed)" />
        </marker>
      </defs>

      <rect x="75" y="12" width="190" height="58" rx="12" fill="var(--gsk-card, #fff)" stroke="var(--gsk-hair, rgba(17,24,39,0.12))" />
      <text x="170" y="47" textAnchor="middle" fontSize="16" fontWeight="600" fill="var(--gsk-ink, #111827)">Your app</text>
      <path d="M 170 70 L 170 116" fill="none" stroke="var(--gsk-purple, #7c3aed)" strokeWidth="1.6" markerEnd="url(#boost-arrow-mobile-accent)" />
      <text x="180" y="98" fontSize="11" fontWeight="500" fill="var(--gsk-purple, #7c3aed)">JSON-RPC</text>

      <rect x="75" y="124" width="190" height="58" rx="12" fill="var(--gsk-purple, #7c3aed)" />
      <text x="170" y="159" textAnchor="middle" fontSize="17" fontWeight="650" fill="var(--gsk-on-accent, #fff)">Boost</text>

      <path d="M 145 182 C 145 222, 84 225, 84 265" fill="none" stroke="var(--gsk-wire, #94a3b8)" strokeWidth="1.5" markerEnd="url(#boost-arrow-mobile)" />
      <text x="76" y="224" textAnchor="middle" fontSize="11" fontWeight="500" fill="var(--gsk-sub, #6b7280)">eligible read</text>
      <rect x="12" y="274" width="144" height="80" rx="12" fill="var(--gsk-card, #fff)" stroke="var(--gsk-gold, #d97706)" />
      <text x="84" y="308" textAnchor="middle" fontSize="15" fontWeight="600" fill="var(--gsk-gold, #d97706)">Goldsky data</text>
      <text x="84" y="329" textAnchor="middle" fontSize="11" fill="var(--gsk-sub, #6b7280)">served by Boost</text>

      <path d="M 195 182 C 195 222, 256 225, 256 265" fill="none" stroke="var(--gsk-wire, #94a3b8)" strokeWidth="1.5" markerEnd="url(#boost-arrow-mobile)" />
      <text x="268" y="224" textAnchor="middle" fontSize="11" fontWeight="500" fill="var(--gsk-sub, #6b7280)">other calls</text>
      <rect x="184" y="274" width="144" height="80" rx="12" fill="var(--gsk-card, #fff)" stroke="var(--gsk-gray, #6b7280)" />
      <text x="256" y="308" textAnchor="middle" fontSize="15" fontWeight="600" fill="var(--gsk-ink, #111827)">Your provider</text>
      <text x="256" y="329" textAnchor="middle" fontSize="11" fill="var(--gsk-sub, #6b7280)">forwarded</text>

      <text x="170" y="397" textAnchor="middle" fontSize="12" fill="var(--gsk-sub, #6b7280)">The response returns through the same Boost URL.</text>
    </svg>
  </div>;

Boost reads the JSON-RPC method and parameters, then chooses the response source. The API key identifies your project's Boost; that project's network configuration supplies the upstream for calls that need your provider.

<BoostDiagram />

## Routing model

| Request | Route | Response headers |
| - | - | - |
| Eligible historical or tip-of-chain read that Goldsky can answer | CDN | `x-cache: HIT`, `x-edge-source: cache` |
| `eth_chainId` or `net_version` | Boost | `x-edge-source: static` |
| Eligible read whose data is not available | Your upstream | `x-cache: MISS`, `x-edge-source: endpoint` |
| `pending`, `safe`, `finalized`, or `earliest` tag, write, trace, state read, or unsupported method | Your upstream | `x-cache: MISS`, `x-edge-source: endpoint` |
| Anything that would forward, when the request asks for [cache-only](#cache-only-mode) | Nobody | `x-cache: MISS`, `x-edge-source: none` |

A failed or incomplete cache lookup falls back to your upstream. A cache miss can add proxy latency, but it does not substitute a different result.

## Methods eligible for indexed data

| Method | Eligible when |
| - | - |
| `eth_blockNumber` | Always eligible |
| `eth_getBlockByNumber` | The block is a concrete hexadecimal height or `latest` |
| `eth_getBlockByHash` | The requested block is available in Goldsky's indexed data |
| `eth_getTransactionByHash` | The requested transaction is available in Goldsky's indexed data |
| `eth_getTransactionReceipt` | The requested receipt is available in Goldsky's indexed data |
| `eth_getLogs` | `fromBlock` and `toBlock` are concrete hexadecimal heights, or `blockHash` is set |
| `eth_getBlockReceipts` | The block is a concrete hexadecimal height |

Eligibility does not guarantee a hit. If Goldsky does not have the requested data, Boost forwards the request.

## Tip of chain

`eth_blockNumber` and `eth_getBlockByNumber` with `latest` are answered from Goldsky's indexed data, which follows your source chain at the tip and through reorgs.

Other tags forward: `pending`, `safe`, `finalized`, and `earliest` on any method, and `latest` on methods other than `eth_getBlockByNumber`. The same rule applies to `eth_getLogs` when either range bound is a tag. Use a concrete hexadecimal height when you want those reads served by Boost.

## Everything else forwards

Writes, traces, and state reads such as `eth_call` and `eth_getBalance` go to your configured upstream. Boost also forwards methods it does not recognize as eligible.

For a forwarded call, Boost preserves the JSON-RPC method, parameters, and ID. The result body comes from your upstream. HTTP headers are handled separately; see [request and response forwarding](/boost/configuration#request-and-response-forwarding).

## Cache-only mode

Add `cache-only=true` and Boost never contacts your upstream. Calls it can answer from Goldsky data are answered; everything that would otherwise forward returns JSON-RPC error `-32099` instead.

Use it when the forward is the cost you are avoiding. Boost itself is free, but a forwarded call still reaches the provider you pay. A backfill, a replay, or any job with a spending ceiling can run against indexed data alone and retry the gaps later.

Send it as a query parameter or a header. The two are equivalent:

```bash theme={"dark"}
curl "https://edge.goldsky.com/boost/ethereum?key=YOUR_KEY&cache-only=true" \
  -X POST -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_getTransactionReceipt","params":["0x..."]}'
```

```bash theme={"dark"}
curl "https://edge.goldsky.com/boost/ethereum?key=YOUR_KEY" \
  -X POST -H 'Content-Type: application/json' \
  -H 'x-boost-cache-only: true' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_getTransactionReceipt","params":["0x..."]}'
```

A refused call returns:

```json theme={"dark"}
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32099,
    "message": "not in Goldsky's cache, and cache-only forbade the forward to your endpoint"
  }
}
```

Boost returns an error rather than an empty result on purpose. `null` already carries meaning here — `eth_getTransactionReceipt` returns `null` for a transaction that does not exist — so answering a miss with `null` would report an absence that Goldsky never verified. Repeat the call without the flag to forward it normally.

`eth_chainId` and `net_version` still answer under cache-only, because Boost synthesizes them and no provider is involved either way. Refused calls report `x-edge-source: none`: not `endpoint`, since nothing reached your upstream.

In a batch, the flag applies per item. Eligible items are served and the rest are refused individually, in one response array.

### Skip-cache

The inverse: `skip-cache=true`, or the `x-boost-skip-cache: true` header, forwards the call to your upstream without reading the cache. Use it to time your provider directly or to fetch a value the cache would otherwise answer. Statics still answer at the edge. The next call without the flag is served from cache as usual; nothing is invalidated.

<Note>
  Write either value as exactly `true`. `1`, `TRUE`, `yes`, and a bare flag all read as "not requested". Sending both flags on one request returns `-32600`; they contradict.
</Note>

## Batch requests

Boost evaluates JSON-RPC batches per item. Eligible items can come from Goldsky data while the remaining items are sent to your upstream together in one onward batch.

* Give every item a unique `id`. JSON-RPC does not guarantee response order, so match results by ID.
* Use `x-edge-billable` as the served-item count. `x-cache` is `HIT` only when Boost serves every item in the batch.
* Keep arrays at 100 items or fewer. Larger arrays are forwarded whole without cache lookups.

For example, a batch where Boost serves 44 of 45 items reports `x-cache: MISS` and `x-edge-billable: 44`.

## Authentication and endpoint selection

The endpoint format is:

```text theme={"dark"}
https://edge.goldsky.com/boost/{chain}?key={your-api-key}
```

The chain path selects the network. The Goldsky key identifies your project's Boost, and that network's configuration selects the active upstream. Your provider URL and persistent provider credentials stay in the configuration rather than traveling in each request.


## Related topics

- [Boost reference](/boost/reference.md)
- [Measure Boost traffic](/boost/observability.md)
- [Cut RPC costs with Boost](/boost.md)
- [Troubleshoot Boost](/boost/troubleshooting.md)
- [Configure Boost upstreams](/boost/configuration.md)
