Nostr Relays — Architecture and Management
- Nostr Relays
Nostr Relays
Dumb pipes. Smart network. Relays are the infrastructure layer that makes Nostr work.
What Relays Do
Relays are WebSocket servers that:
- Accept events from clients (EVENT)
- Store events (optionally, based on kind policy)
- Forward events to subscribers (REQ → EVENT stream)
- Send notices for errors, rate limits, etc.
That’s it. No logic. No feeds. No algorithms. Just store and forward.
Relay Architecture
CLIENT A RELAY CLIENT B
│ │ │
│──EVENT(kind:1)────────▶│ │
│ │──store───────────────────│
│ │ │
│ │◄──REQ(kinds:[1])─────────│
│ │──EVENT (match)──────────▶│
│ │──EVENT (match)──────────▶│
│ │──EOSE────────────────────▶│
Relay Types
Public Relays
- Anyone can connect
- Anyone can publish
- Anyone can read
- Free or paid
Private Relays
- Access controlled
- Whitelisted pubkeys
- Invite-only
- Often for DMs or private communities
Paid Relays
- Pay-per-event or subscription
- Higher quality (less spam)
- Often used for write access
Specialized Relays
- Search relays (kind 10007): indexed search
- DM relays (kind 10050): dedicated to private messages
- Read relays: optimized for content delivery
- Write relays: optimized for event acceptance
Relay Information (NIP-11)
Every relay should serve metadata at its WebSocket endpoint:
GET wss://relay.damus.io
→ NIP-11 JSON document
{
"name": "Damus Relay",
"description": "Public relay for Damus users",
"pubkey": "7e2...",
"contact": "damus@example.com",
"supported_nips": [1, 2, 4, 9, 11, 12, 15, 16, 20, 22, 28, 33, 40],
"software": "strfry",
"version": "0.9.6",
"limitation": {
"max_message_length": 16384,
"max_subscriptions": 20,
"max_filters": 100,
"max_limit": 500,
"max_subid_length": 100,
"min_prefix": 4,
"max_event_tags": 100,
"created_at_lower_limit": 946684800,
"created_at_upper_limit": 2147483647
},
"payments_url": "https://...",
"fees": {
"admission": [{ "amount": 1000000, "unit": "msats" }],
"publication": [],
"subscription": [{ "amount": 5000000, "unit": "msats", "period": 2592000 }]
}
}
My Relays
wss://relay.damus.io — Public, high traffic
wss://nos.lol — Public, reliable
wss://relay.nostr.band — Public, searchable
wss://relay.primal.net — Public, Primal backend
wss://nostr.mom — Public
wss://purplepag.es — Indexing relay
Managed via kind 10002:
{
"kind": 10002,
"tags": [
["r", "wss://relay.damus.io"],
["r", "wss://nos.lol"],
["r", "wss://relay.nostr.band", "read"],
["r", "wss://relay.primal.net"],
["r", "wss://nostr.mom"],
["r", "wss://purplepag.es", "read"]
]
}
Relay Policies
Relays decide what to store/forward. Common policies:
Kind Filtering
Store: kinds 0, 1, 3, 5, 6, 7, 30023, 9735
Reject: kinds 4, 23194, 23195 (ephemeral)
Ignore: kinds 20000-29999 (by design)
Rate Limiting
Max events per minute: 10-100
Max subscription filters: 20-100
Max subscription duration: infinite or time-limited
Content Moderation
Some relays block content. Some don’t. Pick relays that match your values.
Relay Software
| Software | Language | Notes |
|---|---|---|
| strfry | C++ | High performance, NIP-50 search |
| nostream | TypeScript | Feature-rich |
| nostr-rs-relay | Rust | Efficient |
| khatru | Go | Framework for custom relays |
| citrine | Kotlin | Android-friendly |
Attacking & Defending
Attacks on Relays
- Spam: Flood with junk events → rate limiting, POW (NIP-13), paid relays
- DDoS: Overwhelm with connections → connection limits, CDN
- Storage exhaustion: Fill disk → kind filtering, retention limits
- Content injection: Forge events → sig verification on acceptance
Defenses for Users
- Multiple relays: Publish to 3-5 relays for redundancy
- Read relays: Use separate relays for reading
- Private relays: Run your own for sensitive content
- DM relays: Dedicated relay for DMs (kind 10050)
Relay Selection Best Practices
- Audit your relay list: Know who runs each relay
- Diversify: 5-8 relays across different operators
- Separate concerns: Write relays ≠ Read relays ≠ DM relays
- Keep it small: NIP-65 recommends 2-4 of each type
- Spread kind 10002: Publish your relay list everywhere
Running Your Own Relay
# strfry - fast C++ relay
git clone https://github.com/hoytech/strfry
cd strfry && make setup-golpe
make -j4
./strfry relay
Benefits:
- Full control over your data
- No censorship by third parties
- Can archive all your events
- Learn the protocol from the inside
Relay Discovery
Finding relays:
- Purple Pages (purplepag.es): Community-curated relay index
- nostr.watch: Relay monitoring + uptime stats
- User follow lists: See what relays followed users use
- kind 10002: Everyone’s relay list metadata
- NIP-11: Ask a relay for its info
Write a comment