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

# Gateway Setup

export const RunForm = ({path, source, children}) => {
  const url = `https://form.typeform.com/to/jJlpMc8r#path=${path}&source=${source}`;
  return <a href={url}>{children}</a>;
};

Run a gateway when the hosted tiers stop fitting: your application needs dedicated read capacity, you want to offer read service to others, or you want your own limits and your own cache ([when to escalate](/apis/rate-limits)). A gateway follows the chain, reads slices from storage nodes as a staked peer, and serves the [read API](/apis/gateway). What the role is and why it exists is on the [gateways page](/protocol/architecture/gateways); this page gets one running.

<Info>
  Joining the public network as an operator starts with the staking program.
  <RunForm path="tapenet" source="gateway">Fill out the form</RunForm> and we'll help you
  get set up.
</Info>

## Prerequisites

* A machine where memory and disk match your cache plans; the gateway's disk footprint is mostly its slice cache and its indexes.&#x20;
* A reliable Solana RPC endpoint.
* A wallet with SOL and enough TAPE to stake past the network's access threshold, the
  voted minimum stake storage nodes require before they'll serve a peer
  ([why stake gates reads](/protocol/architecture/gateways)). See
  [Tapenet funding](/tapenet/access#fund-a-node).

## Install

[Install Tapedrive](/install) on the machine that will run the gateway.

## Stake

A gateway registers and stakes like a node but never joins the committee. It holds no spools, casts no votes, and owes no storage. The stake is what opens reads from storage nodes.

```bash theme={null}
tape-node keygen --out ~/.tape --name my-gateway

tape-admin node register \
  --identity ~/.tape/identity.json \
  --bls ~/.tape/bls.json \
  --tls ~/.tape/tls.json \
  --address gw.example.com:4040 \
  --name my-gateway

tape-admin node stake --identity ~/.tape/identity.json --amount 1000
```

Note the missing step: no `join-committee`. Registered and staked without joining is exactly what a gateway is.

Stake activates over two epochs. Check the current access threshold before you size your stake.

## Configuration

The same `node.yaml` drives the gateway; the `gateway` section is where its own behavior lives:

```yaml theme={null}
gateway:
  cache:
    max_bytes: 500000000000   # slice cache budget; 0 disables the persistent cache
  metering:                   # request and byte buckets for public traffic
http:                         # the public listener users hit
https:                        # the mTLS side that talks to storage nodes
```

The two listeners have different jobs and should be treated that way: expose `http` to the world, and firewall the `https` peer side the same way you would a storage node's. Size the cache to your working set; the gateway caches slices, so cached content costs about what the decoded objects would ([how gateway caching works](/protocol/architecture/gateways)).

Rate limits and access tiers are yours to set. The defaults match Tapenet's hosted public
tier; loosen or tighten them to match the service you're running
([rate limits](/apis/rate-limits)).

## Run

```bash theme={null}
tape-gateway --config ~/.tape/node.yaml
```

First start bootstraps the indexes by replay, then follows the chain live. A gateway's local state is disposable: delete it and the next start rebuilds it from the chain. That's also what makes scaling out simple. Run more instances behind a load balancer; there's no shared state to coordinate ([the architecture](/protocol/architecture/gateways)).

For unattended operation, run it under systemd. The restart policy pairs with the gateway's disposable state: a crash or a kill restarts clean and re-bootstraps if needed.

```ini theme={null}
[Unit]
Description=Tapedrive gateway
After=network-online.target

[Service]
ExecStart=/usr/local/bin/tape-gateway --config /home/tape/.tape/node.yaml
Restart=on-failure
TimeoutStopSec=30

[Install]
WantedBy=multi-user.target
```

## Serving under load

At saturation the gateway sheds load at the edges instead of buffering without limit. Queues and connection counts are capped, so latency degrades predictably and memory stays flat. The knobs that matter when tuning: the cache budget, the concurrent-request caps, and the per-IP metering.

## Fronting with a CDN

For public content at web scale, put a CDN in front. Tapedrive content caches unusually well, and the integration pattern, cache policies, and caveats live on the [CDN page](/tools/cdn).

## Metrics

A build with the `metrics` cargo feature serves `/v1/metrics` on the HTTP listener ([telemetry](/tools/telemetry) lists every identifier). The alerts worth paging on:

```text theme={null}
# Falling behind the chain (serving stale state)
tape_node_ingest_lag_slots > 300

# Cache no longer absorbing reads
sum(rate(tape_gw_cache_requests_total{result="hit"}[15m]))
  / sum(rate(tape_gw_cache_requests_total[15m])) < 0.5

# Objects failing to decode: not enough verified slices from storage nodes
rate(tape_gw_decode_total{result="insufficient_slices"}[10m]) > 0

# Latency and errors
histogram_quantile(0.99, sum by (le) (rate(tape_http_request_duration_seconds_bucket[5m]))) > 1
sum(rate(tape_http_request_duration_seconds_count{status_class="5xx"}[5m]))
  / sum(rate(tape_http_request_duration_seconds_count[5m])) > 0.01
```

The pairing to watch is sync lag against serving metrics; [telemetry](/tools/telemetry) explains why those two belong together.
