A fast, lightweight nostr relay written in Zig.
- Fast: ~9x higher throughput than strfry, sub-millisecond p99 latency
- Small: Single binary, ~11MB RAM at idle
- Simple: One command to run your personal relay with your feed
- Spider Mode: Automatically syncs events from people you follow
docker run -d -p 7777:7777 -v wisp-data:/data ghcr.io/privkeyio/wisp --spider-admin npub1yourkey...Download the latest release or build from source:
# 1. Install dependencies (requires Zig 0.16.0)
sudo apt install -y liblmdb-dev libsecp256k1-dev libssl-dev
# 2. Build
git clone https://github.com/privkeyio/wisp && cd wisp
zig build -Doptimize=ReleaseFast
# 3. Run (replace with your npub)
./zig-out/bin/wisp --spider-admin npub1yourkey...That's it. Wisp will fetch your follow list, sync notes from popular relays, and serve them at ws://localhost:7777. Add this relay URL to your Nostr client.
For more options, see wisp.toml.example.
- NIPs: 1, 2, 9, 11, 13, 16, 33, 40, 42, 45, 50, 65, 70, 77, 86
- LMDB storage (no external database)
- Spider mode for syncing events from external relays
- Import/export to JSONL
- Prometheus metrics at
GET /metrics
Operational metrics are exposed in Prometheus format at GET /metrics on the
relay's port (connections, events stored/rejected/broadcast, REQ count, rate
limiting). The endpoint honors the relay's IP allowlist/blocklist, so restrict
it there or at your reverse proxy/firewall if you don't want it public.
./zig-out/bin/wisp export > backup.jsonl
./zig-out/bin/wisp import < backup.jsonlCopy wisp.toml.example to wisp.toml and customize, or use environment variables with the WISP_ prefix:
WISP_PORT=8080 ./zig-out/bin/wispEnvironment variables override the config file. See the Configuration reference for every setting, its environment variable, default, and meaning.
To make your relay publicly accessible with TLS, run wisp with Caddy:
# Run wisp
docker run -d --restart always -p 7777:7777 -v wisp-data:/data \
ghcr.io/privkeyio/wisp --spider-admin npub1yourkey...
# Install Caddy for automatic TLS
sudo apt install -y caddyCreate /etc/caddy/Caddyfile:
relay.yourdomain.com {
reverse_proxy localhost:7777
}
sudo systemctl restart caddyYour relay is now live at wss://relay.yourdomain.com.
Peak write throughput, all relays at 100% delivery:
| Relay | Events/sec | p99 Latency | Memory (RSS) |
|---|---|---|---|
| Wisp | 25,600 | 0.28 ms | 11 MB |
| nostr-rs-relay | 5,400 | 5.9 ms | 20 MB |
| strfry | 2,800 | 2.9 ms | 3 MB |
nostr-bench, 5,000 events x 4 workers at peak rate (--rate 0), native release builds on a 16-core Linux host, with the event-rate limit raised. RssAnon sampled during the run. These are peak figures with Wisp in sync = none (non-durable); Wisp's default is sync = meta (durable, never corrupts), which trades raw throughput for crash safety. strfry and nostr-rs-relay write durably by default, so a fair durable comparison runs Wisp in meta/full (see benchmarks). Wisp leads on throughput (~9x strfry, ~5x nostr-rs-relay) and p99 latency; strfry stays smallest in memory.
See CONTRIBUTING.md for guidelines on reporting issues and submitting pull requests.
See CHANGELOG.md for a history of changes to this project.
MIT
