Skip to content
Back to skills

Slv Jetstreamer

ASecurity

Build, configure, and run anza-xyz/jetstreamer + ClickHouse on a dedicated analytics node. Streams Old Faithful CAR archives at multi-million-TPS into ClickHouse so historical Solana data is queryable via SQL (program_invocations, slot_status, pubkey_mentions). Includes hourly backfill timer and a rolling-window retention option.

  • 89 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added May 26, 2026
databasesrustsqlnodegitapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add ValidatorsDAO/slv --skill slv-jetstreamer --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Slv Jetstreamer?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Slv Jetstreamer
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/validatorsdao-slv-jetstreamer/badge)](https://www.skillsdirectory.com/skills/validatorsdao-slv-jetstreamer)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: slv-jetstreamer
description: Build, configure, and run anza-xyz/jetstreamer + ClickHouse on a dedicated analytics node. Streams Old Faithful CAR archives at multi-million-TPS into ClickHouse so historical Solana data is queryable via SQL (program_invocations, slot_status, pubkey_mentions). Includes hourly backfill timer and a rolling-window retention option.
---

# SLV Jetstreamer Skill

`jetstreamer` is anza-xyz's high-throughput Solana ETL engine: it streams the Old
Faithful CAR archive directly into a local ClickHouse instance and produces
query-ready aggregations (program invocation counts, slot statuses, pubkey
mentions, …). Together with the `slv-rpc` of1 rolling cache, it gives a
clean separation:

| Layer | Component | Role |
|---|---|---|
| **JSON-RPC** (per-call) | `yellowstone-faithful` (Index RPC) + 30-epoch index cache | `getTransaction` / `getBlock` / `getBlockTime` etc. |
| **SQL analytics** (bulk) | `jetstreamer` + ClickHouse | Cross-epoch aggregations, program-level joins, MEV / DEX research |

Jetstreamer is **not** a server. It runs as a one-shot ETL per epoch and exits;
ClickHouse is the long-running query surface.

## Hardware target

| Resource | Recommended |
|---|---|
| CPU | AMD EPYC 64C+ (jetstreamer hits 2.7 M TPS+ ingest with all cores) |
| RAM | 128 GB+ (754 GB optimal for full-fat ClickHouse buffers) |
| Disk | 4-8 TB NVMe (RAID0 recommended for max write bandwidth — derived data is rebuildable from Old Faithful) |
| Network | 10 Gbps+ (50 Gbps demonstrated to fully saturate ingest path) |
| OS | Ubuntu 24.04, kernel 6.14+ |
| Toolchain | **Clang 16** (RocksDB compatibility — Clang 17/18 do *not* work), GCC 13, Rust (rustup, toolchain pinned by rust-toolchain.toml in jetstreamer repo) |

## Disk layout

The reference layout combines two NVMes into one mdadm RAID0 stripe:

```
/dev/nvme0n1 ─┐
              ├─ mdadm RAID0 (chunk=1M) ─► /dev/md0 ─► XFS @ /mnt/jetstreamer
/dev/nvme1n1 ─┘                                       (noatime,inode64,
                                                       logbufs=8,logbsize=256k)
```

Mount options chosen for sequential write bandwidth + many-small-files (CH parts):
`noatime,nodiratime,inode64,logbufs=8,logbsize=256k`. Format with
`mkfs.xfs -d agcount=64 -l size=1g` for parallel allocation groups + a 1 GiB
internal log (XFS log max).

Production benchmark on this layout: **8.1 GB/s sequential write, 13.0 GB/s
sequential read** (direct I/O).

## Components installed

| Path | Purpose |
|---|---|
| `/mnt/jetstreamer/jetstreamer/` | git clone of `anza-xyz/jetstreamer` |
| `/usr/local/bin/jetstreamer` | symlink → `target/release/jetstreamer` |
| `/usr/local/bin/clickhouse` | bundled binary extracted from jetstreamer's first run |
| `/usr/local/bin/jetstreamer-backfill.sh` | rolling backfill script |
| `/etc/clickhouse-server/config.xml` | base CH config (jetstreamer's preprocessed copy) |
| `/etc/clickhouse-server/config.d/01-perf.xml` | tuned memory + concurrency + merge_tree |
| `/etc/clickhouse-server/config.d/02-users.xml` | redirect users_xml → /etc/clickhouse-server/users.xml |
| `/etc/clickhouse-server/users.d/01-perf.xml` | per-query profile (max_memory_usage, threads) |
| `/etc/systemd/system/clickhouse-server.service` | persistent CH server |
| `/etc/systemd/system/jetstreamer-backfill.{service,timer}` | hourly ingest of new epochs |
| `/mnt/jetstreamer/clickhouse-data/` | persistent CH data (~50-200 GB / epoch in storage tables) |

## ClickHouse tuning highlights

For a 754 GB-RAM 64-core node:
- `max_server_memory_usage_to_ram_ratio = 0.65` → ~490 GiB
- `background_pool_size = 32`, `background_merges_mutations_concurrency_ratio = 4`
- `merge_tree.parts_to_throw_insert = 10000`, `parts_to_delay_insert = 8000`
- per-query: `max_memory_usage = 30 GiB`, `max_threads = 32`
- sysctl: `vm.max_map_count=2097152`, `vm.swappiness=1`, `net.core.somaxconn=4096`
- LimitNOFILE=1048576

## Jetstreamer tuning highlights

| Variable | Value | Why |
|---|---|---|
| `JETSTREAMER_THREADS` | `120` | leave 8 logical cores for OS + ClickHouse merges |
| `JETSTREAMER_BUFFER_WINDOW` | `64GiB` | aggressive ripget prefetch for high-bandwidth links |
| `JETSTREAMER_CLICKHOUSE_MODE` | `remote` | use the persistent systemd CH; do not spawn helper |
| `JETSTREAMER_CLICKHOUSE_DSN` | `http://localhost:8123` | local CH HTTP endpoint |

## Hourly rolling backfill

`jetstreamer-backfill.timer` fires `OnCalendar=hourly` and:
1. Asks `api.mainnet-beta.solana.com` for the current epoch.
2. Probes Old Faithful for the latest *published* epoch (one or two below tip).
3. Queries ClickHouse for slot ranges that already have ≥ 99% coverage.
4. Runs `jetstreamer <epoch>` for each missing epoch (in order).
5. Optional: `WINDOW=N` env enables `ALTER TABLE … DELETE WHERE slot < (latest-N)*432000` to drop old epochs.

## Querying

ClickHouse listens on `:8123` (HTTP) and `:9000` (native).  Query examples:

```sql
-- Top 10 non-vote programs by invocation count, last fully-ingested epoch
SELECT
  base58Encode(toString(program_id)) AS program,
  sum(count) AS invocations,
  formatReadableQuantity(sum(total_cus)) AS total_cus
FROM program_invocations
WHERE is_vote = 0
GROUP BY program_id
ORDER BY invocations DESC
LIMIT 10;

-- Slots ingested per epoch
SELECT intDiv(slot, 432000) AS epoch, count() AS slots
FROM jetstreamer_slot_status
GROUP BY epoch
ORDER BY epoch;

-- Total transaction throughput per epoch
SELECT
  intDiv(slot, 432000) AS epoch,
  sum(transaction_count) AS txs,
  sum(non_vote_transaction_count) AS non_vote_txs
FROM jetstreamer_slot_status
GROUP BY epoch
ORDER BY epoch;
```

ClickHouse has built-in `base58Encode` / `base58Decode` — no UDF needed for
displaying Solana addresses.

## Ansible entrypoint

`template/<VERSION>/ansible/cmn/install_jetstreamer.yml`. Key inventory vars:

| Variable | Default | Notes |
|---|---|---|
| `jetstreamer_data_dir` | `/mnt/jetstreamer` | Where RAID0 + XFS mount, repo, CH data live |
| `jetstreamer_raid_devices` | `['/dev/nvme0n1', '/dev/nvme1n1']` | Will be wiped+combined |
| `jetstreamer_raid_chunk_kb` | `1024` | mdadm chunk size |
| `jetstreamer_window_epochs` | `0` | `0` = no rotation; `>0` enables `ALTER … DELETE` |
| `jetstreamer_threads` | `120` | `JETSTREAMER_THREADS` |
| `jetstreamer_buffer_window` | `64GiB` | `JETSTREAMER_BUFFER_WINDOW` |
| `jetstreamer_max_server_memory` | `536870912000` (~500 GiB) | `<max_server_memory_usage>` |
| `jetstreamer_run_initial_ingest` | `false` | If `true`, foreground-runs the first backfill (heavy; days) |

The playbook is destructive on the first run (RAID0 reformats the listed
NVMes). Only target nodes that are dedicated jetstreamer hosts.

## Known throughput (production)

- Cold ingest of one recent epoch (~500 M txs): **8 min** with bundled CH, **5 min** with persistent CH (38% faster).
- Sustained ingest throughput: **1.7 M TPS** sustained, **2.8 M TPS** peak ramp.
- Per-epoch CH storage: ~2-3 GB compressed for `program_invocations` + `jetstreamer_slot_status` tables.

## Known ClickHouse pitfalls

- `<users_xml><path>` in the bundled config defaults to the data dir — must override to `/etc/clickhouse-server/users.xml` via a `replace="replace"` `<user_directories>` block in `config.d/`.
- `discard=async` mount option for XFS is rejected by some kernels; use plain mount opts.
- ClickHouse RuntimeDirectory needs `/run/clickhouse-server`; declare in the unit (`RuntimeDirectory=clickhouse-server`).
- `/mnt` defaulting to mode 0700 (some Solana host images) blocks the `clickhouse` system user from traversing — `chmod 0755 /mnt`.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.