Chapter 11
The ecosystem
Relays, clients and NIPs, in numbers: who runs Nostr, what they run, and how it grew.
Time to zoom out! Grab your binoculars: we're going bird-watching across the whole Nostr flock.
Sources
- NIP-66 relay monitors (nostr.watch) fresh Kind 30166 events from wss://relay.nostr.watch, wss://monitorlizard.nostr1.com, wss://relaypag.es; announced monitors only, signatures verified, last 24h. Partial data: wss://relay.nostr.watch stopped answering early, so a few relays may be missing.
- nostr-protocol/nips fresh NIP files, README list and kinds table at HEAD; growth from each file's first commit.
- nostrapps.com + project sites curated Hand-picked notable clients; not an exhaustive census.
A city with no city hall
So far we’ve looked at Nostr up close: one
Picture a city where nobody owns the roads. Anyone can open a post office (a relay), anyone can
build a car (a client, the app you read and write with), and the traffic rules (the
Which raises a fun question: if nobody is in charge, how do you even count the city?
Counting a network that has no list
There is no registry of relays. Spinning one up is like opening a lemonade stand: you don’t ask permission. So instead of asking a central authority, we ask the network itself.
Volunteer monitors constantly knock on relays’ doors: “Are you open? What do you support? Do you
charge?” Then they publish what they found as ordinary, signed Nostr events. Anyone can read those
reports with a normal
These numbers are a snapshot, taken once and saved with the site, so the page never pings anyone while you read. Check the “Data as of” badge above, and open Sources to see exactly where each number came from.
Under the hood: NIP-66 relay reports Show details
NIP-66 defines two event kinds:
- kind 10166: a monitor’s announcement (“I check relays every hour, here are my timeouts”).
- kind 30166: a relay discovery report. It’s an
whoseaddressable event Addressable event: A replaceable event identified by kind, author and a d tag, so one person can have many of them (kinds 30000–39999).dtag is the relay URL, so each monitor keeps exactly one current report per relay.
A real report looks like this (trimmed):
{
"kind": 30166,
"pubkey": "<monitor pubkey>",
"content": "{\"software\":\"git+https://github.com/hoytech/strfry.git\",\"supported_nips\":[1,2,4,9,11,40]}",
"tags": [
["d", "wss://some.relay/"],
["n", "clearnet"],
["N", "1"], ["N", "11"], ["N", "40"],
["R", "!payment"],
["R", "auth"],
["rtt-open", "234"]
]
}N tags list supported NIPs, R tags list requirements (a ! prefix means “not required”), n is
the network (clearnet, tor, i2p, loki), and content may carry the relay’s
NIP-11 info document. Reading them with
nostr-tools:
import { SimplePool } from "nostr-tools/pool";
import { verifyEvent } from "nostr-tools/pure";
const pool = new SimplePool();
const since = Math.floor(Date.now() / 1000) - 24 * 3600;
const reports = await pool.querySync(["wss://relay.nostr.watch"], { kinds: [30166], since });
const relays = new Set(
reports.filter(verifyEvent).map((e) => e.tags.find((t) => t[0] === "d")?.[1]),
);
console.log(`${relays.size} relays reported in the last 24h`);NIP-66 itself warns that a monitor can be wrong or lie, and that clients must never require these reports. So our script only counts reports from pubkeys that published a kind 10166 announcement, verifies every signature, merges reports from several monitors, and records any monitor relay that timed out in the snapshot’s source notes. Relays monitors can’t reach (or don’t know about) are missing, so treat the totals as a floor, not a census.
Explore the snapshot
Here’s the city from above. Hop between the four views: Relays (who is running the post offices), NIPs (which traffic rules they follow), Growth (how the rulebook grew) and Clients (which cars you can drive). Visit all four for a little celebration.
Ecosystem explorer
A snapshot of Nostr, counted from the protocol itself. Pick a view to dig in.
Sources
- NIP-66 relay monitors (nostr.watch) fresh Kind 30166 events from wss://relay.nostr.watch, wss://monitorlizard.nostr1.com, wss://relaypag.es; announced monitors only, signatures verified, last 24h. Partial data: wss://relay.nostr.watch stopped answering early, so a few relays may be missing.
- nostr-protocol/nips fresh NIP files, README list and kinds table at HEAD; growth from each file's first commit.
- nostrapps.com + project sites curated Hand-picked notable clients; not an exhaustive census.
| Software | Relays |
|---|---|
| strfry | 305 |
| nostr-rs-relay | 278 |
| haven | 165 |
| pyramid | 54 |
| nostr | 44 |
| khatru | 36 |
| nostream | 32 |
| not reported | 233 |
| everything else | 260 |
- Clearnet 90.3%
- Tor 9.3%
- I2P 0.4%
| Label | Value | Share |
|---|---|---|
| Clearnet | 1,271 | 90.3% |
| Tor | 131 | 9.3% |
| I2P | 5 | 0.4% |
| Total | 1,407 | 100% |
45 relays ask for payment and 32 require login (NIP-42 AUTH) before you can read or write.
What the relay numbers tell us
Look at the Relays view and two things jump out.
Diversity. No single program runs the network. A handful of open-source relay programs
(strfry, nostr-rs-relay, haven, khatru-based relays and many more) split the work, and a long
tail of homemade ones fill in the gaps. If one of them had a bug tomorrow, the others would keep
humming. That’s
Choice. Most relays are free and open, but some ask for payment (a
Under the hood: asking a relay about itself (NIP-11) Show details
Every relay can describe itself. Send a plain HTTP GET to the relay’s URL (with https:// instead
of wss://) and the header Accept: application/nostr+json, and you get its
NIP-11 document:
const res = await fetch("https://relay.damus.io", {
headers: { Accept: "application/nostr+json" },
});
const info = await res.json();
console.log(info.software, info.supported_nips, info.limitation?.payment_required);The software field is “a URL to the project’s homepage” (that’s how we grouped relays by program),
supported_nips is a list of NIP numbers, and limitation holds flags like auth_required and
payment_required. Monitors copy this document into the content of their 30166 reports, which is
how our snapshot got it without contacting each relay itself.
NIPs: a rulebook you can pick from
A REQ/EVENT/EOSE conversation. Everything else is optional.
Think of it like a restaurant menu rather than a law book. Each relay and each app picks the dishes it wants to serve. That’s why, in the NIPs view, NIP-01 is nearly universal while newer ideas are still catching on. You’ll also notice some veterans like NIP-12, NIP-16, NIP-20 and NIP-33: those were folded into NIP-01 long ago, but many relays still list them, a nice reminder that the network upgrades slowly and unevenly.
The Growth view shows the rulebook getting thicker over time. Drag the slider back to 2022 and
watch it grow. Growth isn’t only additions, either: a number of NIPs are now marked
unrecommended (the old
Under the hood: where NIPs live Show details
NIPs live in one GitHub repository,
github.com/nostr-protocol/nips. Each NIP is a Markdown file
named with two hexadecimal characters (01.md, 5A.md, C7.md), and the README holds the list of
NIPs (unrecommended ones are struck through) plus a table of known event kinds.
Our growth curve is computed from git history: for every NIP file, the date of the commit that first added it, counted per quarter. A tree-only clone keeps that fast:
git clone --filter=blob:none --no-checkout https://github.com/nostr-protocol/nips
cd nips
git log --first-parent -m --no-renames --diff-filter=A --name-only --format=@%aI HEADThe README’s acceptance criteria say a NIP should be fully implemented in at least two clients and one relay (when applicable), and must stay optional and backwards-compatible. Is a single repo a point of control? The README tackles that head-on: the index can be challenged, moved or even forked, and apps are always free to ignore a NIP they disagree with.
So many apps, one identity
Open the Clients view and filter by the device in your pocket. There’s something for every taste: Twitter-style timelines, photo feeds, group chats, long-form blogs, live streams, even a marketplace and an app store.
Here’s the trick, and it’s the whole reason this ecosystem can exist: the apps don’t own
you. Your identity is your key, your posts sit on relays, and your
That also means apps compete on being good, not on holding your friends hostage. Don’t like how one app looks? Try another this afternoon. You lose nothing.
Under the hood: how apps find each other (NIP-89) Show details
Our client list is hand-picked (from nostrapps.com and each project’s site), because there’s no machine-readable census of apps. But Nostr has a way for apps to advertise themselves: NIP-89.
- An app publishes a kind 31990 “handler information” event saying which event kinds it can
display, and how to link into it (per platform:
web,ios,android). - A user can publish a kind 31989 recommendation: “for kind 30023 long-form posts, I like this app”.
So when your client meets a kind it doesn’t understand, it can query
{ "kinds": [31989], "#d": ["30023"] } among the people you follow and say “open this in Habla”.
Your follow list is also how apps find you: with the
Reading ecosystem stats like a pro
Every Nostr dashboard you’ll find online shows different numbers, and that’s normal. Before you trust a figure, ask three questions:
- Who measured it, and how? Our relays come from NIP-66 monitors; another site might crawl relay lists from user profiles, and get a bigger (or smaller) number.
- When? Relays come and go daily. Our snapshot shows its date at the top of the page.
- What’s missing? Private relays, relays monitors haven’t discovered yet, and apps that never listed themselves are invisible to any census.
That’s not a weakness to hide. A network nobody owns is a network nobody can fully count, and that’s exactly the point.
Quick check
Takeaways
- Nostr has no headquarters: well over a thousand independent relays, run by different people with different software, make up the network.
- We can count relays using Nostr itself: monitors publish signed NIP-66 reports (kind 30166) that anyone can read.
- NIPs are optional specs. NIP-01 is the shared core; every other feature is adopted relay by relay and app by app.
- Apps are interchangeable: your key, posts and follow list travel with you, so switching clients loses nothing.
- Numbers like these are a snapshot, not a census: always check the date and the source.