How Nostr Works: Technical Deep-Dive
Comprehensive technical explanation of the Nostr protocol. Learn about events, relays, clients, cryptographic signatures, and the architecture that makes decentralized social networking possible.
Introduction
Nostr is beautifully simple. While other decentralized protocols require blockchains, complex consensus mechanisms, or federated server networks, Nostr works with just three components: keys, events, and relays.
This guide explains how Nostr actually works under the hood - accessible enough for non-developers, but detailed enough for those who want to understand the architecture.
The Core Components
1. Cryptographic Keys (Identity)
Your identity on Nostr is a cryptographic key pair generated using the secp256k1 elliptic curve (the same used in Bitcoin).
Key Generation
When you create a Nostr identity, the process is:
- Generate a private key - A random 256-bit number (32 bytes)
- Derive the public key - Mathematically derived from the private key
- Encode for human use - Convert to readable formats
Key Formats
Hexadecimal (Raw):
Private: 3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d
Public: 7e7e9c42a91bfef19fa929e5fda1b72e0ebc1a4c1141673e2794234d86addf4e
Bech32 (User-Friendly):
Private (nsec): nsec180cvv83m04t28fh7wx55c6q95typ8wl0n0utzg49jy58q43pl38q06xw2u
Public (npub): npub10elfcspfr0l0rxa69rjlmgdhuchdcxjvz9qkwulz72pp6p4dmasqr2tzag
The bech32 format is what you see in Nostr clients. It’s:
- Easier to read
- Includes error detection
- Has type prefixes (
nsecfor private,npubfor public)
Cryptographic Properties
Public Key:
- Mathematically derived from private key
- Cannot be used to derive the private key (one-way function)
- Safe to share publicly
- Your permanent identity
Private Key:
- Must be kept secret
- Used to create digital signatures
- Proves you control the public key
- If lost, identity is unrecoverable
2. Events (The Data Structure)
Everything in Nostr is an event. A post, a like, a follow list, a profile update - all are events.
Event Structure
An event is a JSON object with this structure:
{
"id": "event_identifier_hash",
"pubkey": "author_public_key",
"created_at": unix_timestamp,
"kind": event_type_number,
"tags": [["tag_name", "tag_value"]],
"content": "the actual content",
"sig": "cryptographic_signature"
}
Let’s break down each field:
Event Fields Explained
id (Event Identifier):
- SHA-256 hash of the event
- Uniquely identifies this event
- Calculated from: pubkey + created_at + kind + tags + content
- Example:
a0b1c2d3e4f5...
pubkey (Author’s Public Key):
- The 32-byte public key of the event creator
- In hexadecimal format
- Tells everyone who created this event
created_at (Timestamp):
- Unix timestamp (seconds since 1970)
- When the event was created
- Example:
1705680000(January 19, 2025)
kind (Event Type):
- Number indicating what type of event this is
- Defined in NIPs (Nostr Implementation Possibilities)
- Examples:
0= Profile metadata1= Short text note (like a tweet)3= Contact list (who you follow)4= Encrypted direct message7= Reaction (like/emoji)
tags (Metadata):
- Array of arrays
- Provides additional context
- Examples:
["e", "event_id"]- References another event["p", "pubkey"]- Mentions a user["t", "bitcoin"]- Hashtag["r", "relay_url"]- Relay recommendation
content (The Actual Data):
- The message, profile info, or data
- Plain text for public posts
- Encrypted for DMs (NIP-04)
- JSON for structured data (profiles)
sig (Signature):
- Cryptographic signature of the event
- Created by signing the event ID with the private key
- Proves:
- This event was created by the owner of the public key
- The content hasn’t been modified
- The event is authentic
Example Event (Short Note)
Here’s what a simple post looks like:
{
"id": "8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9",
"pubkey": "7e7e9c42a91bfef19fa929e5fda1b72e0ebc1a4c1141673e2794234d86addf4e",
"created_at": 1705680000,
"kind": 1,
"tags": [
["t", "nostr"],
["t", "decentralization"]
],
"content": "Just learned how Nostr works. Mind blown by the simplicity! 🤯",
"sig": "signature_of_entire_event_json"
}
This event is:
- A short text note (kind 1)
- Posted by someone with that public key
- Tagged with #nostr and #decentralization
- Signed to prove authenticity
3. Relays (The Distribution Network)
Relays are simple servers that:
- Accept events from clients
- Store events (temporarily or permanently)
- Send events to clients who request them
What Relays Do
Accept Events:
Client → Relay: "Here's a new event I created"
Relay: Checks signature, stores event, confirms receipt
Distribute Events:
Client → Relay: "Send me all events from these public keys"
Relay: Sends matching events as they arrive
That’s It!
Relays don’t:
- Create events (only clients do)
- Modify events (they’d break the signature)
- Have special authority
- Know your private key
- Control your identity
Relay Communication Protocol
Clients talk to relays using WebSockets with a simple JSON protocol.
Client Sends Event:
["EVENT", {event_object}]
Client Subscribes to Events:
["REQ", "subscription_id", {"kinds": [1], "authors": ["pubkey1", "pubkey2"]}]
Relay Sends Event:
["EVENT", "subscription_id", {event_object}]
Client Closes Subscription:
["CLOSE", "subscription_id"]
Simple, elegant, no bloat.
Relay Types
Public Free Relays:
- Open to everyone
- May have spam issues
- Good for reach
- Example: wss://relay.damus.io
Paid Relays:
- Require payment (usually Lightning)
- Better spam filtering
- More reliable
- Example: wss://nostr.wine
Private Relays:
- Invite-only or personal
- Full control over content
- Maximum privacy
- Run your own!
Specialized Relays:
- Media relays (images, video)
- Search relays (indexed content)
- Community relays (specific topics)
- Archive relays (long-term storage)
4. Clients (The User Interface)
Clients are applications that:
- Manage your private key
- Create and sign events
- Connect to relays
- Display content
- Provide user interface
What Clients Do
Key Management:
- Generate new keys
- Store private key securely (or integrate with key managers)
- Sign events using the private key
Event Creation:
- Compose posts, reactions, profile updates
- Format as proper event JSON
- Calculate event ID (hash)
- Sign with private key
Relay Communication:
- Connect to multiple relays via WebSocket
- Subscribe to relevant events
- Publish your events
- Receive events in real-time
Content Display:
- Parse event JSON
- Verify signatures
- Render in user-friendly format
- Handle media, links, mentions
The Complete Flow: Publishing a Post
Let’s walk through what happens when you post “Hello Nostr!”
Step 1: Compose (In Client)
You type: “Hello Nostr!”
Your client creates an event structure:
{
"pubkey": "your_public_key",
"created_at": 1705680000,
"kind": 1,
"tags": [],
"content": "Hello Nostr!"
}
Step 2: Create Event ID (In Client)
The client:
- Serializes the event data in a specific format
- Computes SHA-256 hash
- This hash becomes the event
id
{
"id": "computed_hash_of_event",
"pubkey": "your_public_key",
"created_at": 1705680000,
"kind": 1,
"tags": [],
"content": "Hello Nostr!"
}
Step 3: Sign Event (In Client)
The client:
- Takes the event ID
- Signs it using your private key (Schnorr signature)
- Adds signature to event
{
"id": "computed_hash",
"pubkey": "your_public_key",
"created_at": 1705680000,
"kind": 1,
"tags": [],
"content": "Hello Nostr!",
"sig": "cryptographic_signature_of_id"
}
Step 4: Publish to Relays (Client → Relays)
Your client sends this event to all relays you’re connected to:
Client → Relay 1: ["EVENT", {event}]
Client → Relay 2: ["EVENT", {event}]
Client → Relay 3: ["EVENT", {event}]
Step 5: Relay Verification (At Each Relay)
Each relay:
- Receives the event
- Verifies the signature matches the pubkey
- Checks the ID hash is correct
- Stores the event
- Confirms receipt to your client
Relay → Client: ["OK", "event_id", true, ""]
Step 6: Distribution (Relay → Other Clients)
When someone following you connects to a relay:
Their Client → Relay: "Send me events from [your_pubkey]"
Relay → Their Client: ["EVENT", "subscription_id", {your_event}]
Their client:
- Receives your event
- Verifies the signature (proves you created it)
- Displays “Hello Nostr!” in their feed
Done! Decentralized publishing complete.
Why This Design is Brilliant
1. No Central Authority
- No company controls your identity (it’s a key pair)
- No platform can ban you (they don’t control your keys)
- No algorithm manipulates your feed (client decides what to show)
- No single point of failure (many relays)
2. Extreme Simplicity
- Events are just JSON objects
- Relays are simple servers (can be built in a weekend)
- No complex consensus (no blockchain needed)
- No cryptocurrency required (though Lightning integrates nicely)
3. Censorship Resistance
- If one relay bans you, use another
- If all relays ban you, run your own
- Your identity persists (keys don’t depend on relays)
- Content can be replicated across unlimited relays
4. Portability
- Same identity works in all clients
- Switch clients anytime
- No data lock-in
- True user ownership
5. Scalability
- More users = more relays naturally emerge
- No global state to synchronize
- Clients only fetch what they need
- Relays can specialize (media, text, communities)
Advanced Concepts
Event Kinds (Types of Content)
The kind field enables different types of content:
Basic Kinds:
0- Profile metadata (name, bio, picture)1- Short text note2- Recommend relay3- Contact list (follows)4- Encrypted DM5- Event deletion request7- Reaction (like, emoji)
Advanced Kinds:
30023- Long-form article30078- Application-specific data1984- Report/flag content40- Channel creation41- Channel metadata42- Channel message
NIPs define new kinds as the protocol evolves.
Replaceable Events
Some event kinds are “replaceable” - newer events replace older ones.
Example: Profile metadata (kind 0)
- You post a profile update
- If you post another profile update later
- Relays should keep only the newest one
- Saves storage, ensures up-to-date info
Ephemeral Events
Some events are temporary (kinds 20000-29999):
- Not stored by relays
- Only distributed to active subscribers
- Useful for real-time data (typing indicators, presence)
Parameterized Replaceable Events
Events that can be replaced but are identified by additional parameters beyond just pubkey and kind.
Example: Blog posts (kind 30023)
- Each post has a unique identifier in tags
- Can be updated by publishing a newer version
- Relays keep the latest version of each unique post
Filters and Queries
Clients use filters to request specific events from relays:
{
"kinds": [1, 7], // Only text notes and reactions
"authors": ["pubkey1"], // From specific authors
"#t": ["bitcoin"], // With specific tags
"since": 1705680000, // After timestamp
"limit": 50 // Maximum 50 events
}
Relays return matching events.
Security Model
What’s Secure
Authenticity:
- Signatures prove events are genuine
- Can’t forge events (would need private key)
- Can’t modify events (would break signature)
Identity Ownership:
- Only you control your private key
- Only you can create events as you
- No platform can impersonate you
What’s Not Secure
Privacy:
- All posts are public by default
- Relays can see who you follow
- Timing analysis possible
- IP addresses visible to relays (use Tor/VPN)
Deletion:
- Events may persist on relays
- Deletion (kind 5) is a request, not a guarantee
- Treat all posts as permanent
DM Encryption (NIP-04):
- Better than plaintext
- Not as secure as Signal/WhatsApp
- Use dedicated secure messaging for sensitive comms
Comparison to Other Protocols
Nostr vs ActivityPub (Mastodon)
Nostr:
- Identity: Cryptographic keys (portable)
- Servers: Relays (simple, dumb)
- Accounts: No accounts, just keys
- Migration: Seamless (same keys everywhere)
ActivityPub:
- Identity: username@server (tied to server)
- Servers: Complex, federated
- Accounts: Traditional server accounts
- Migration: Difficult, data loss
Nostr vs AT Protocol (Bluesky)
Nostr:
- Architecture: Simple (keys + relays)
- Identity: Self-sovereign keys
- Infrastructure: Anyone can run relay
- Complexity: Very low
AT Protocol:
- Architecture: Complex (DIDs, PDSs, BGS, AppViews)
- Identity: DIDs (more complex)
- Infrastructure: More centralization
- Complexity: Higher
Nostr vs Blockchain Social
Nostr:
- Data: Stored on relays
- Cost: Free (or cheap paid relays)
- Speed: Instant
- Scalability: Excellent
Blockchain Social:
- Data: On blockchain
- Cost: Transaction fees
- Speed: Block time delays
- Scalability: Limited by chain
Performance Considerations
Network Efficiency
Multi-Relay Strategy:
- Connect to 5-10 relays
- Balance redundancy and bandwidth
- Use closer relays for speed
Selective Subscriptions:
- Don’t subscribe to everything
- Filter by follows, topics, time
- Close subscriptions when done
Caching:
- Clients cache events locally
- Reduces relay queries
- Faster user experience
Relay Optimization
Indexing:
- Relays index events by kind, author, tags
- Fast queries
- Minimal computational overhead
Storage:
- Ephemeral events not stored
- Replaceable events save space
- Specialized relays (text-only, no media)
Future Developments
Coming Improvements
Better Spam Filtering:
- Proof-of-work requirements (NIP-13)
- Web of trust
- Paid relays
- Reputation systems
Enhanced Privacy:
- Better DM encryption (NIP-44)
- Private relays
- Tor integration standard
- Anonymous posting options
Scaling Solutions:
- Specialized relay types
- Content delivery networks
- Relay discovery protocols
- Optimized event formats
New Use Cases:
- Decentralized marketplaces
- Social graphs for apps
- Identity verification
- Reputation systems
- DAO coordination
Conclusion
Nostr works through elegant simplicity:
Keys provide identity ownership Events structure all data Relays distribute content Clients create user experiences
No blockchain, no tokens, no complex consensus - just cryptography, simple servers, and open standards.
This simplicity is Nostr’s superpower. It’s easy to:
- Understand the protocol
- Build clients and relays
- Add new features (NIPs)
- Scale infrastructure
- Resist censorship
The architecture isn’t perfect, but it’s good enough - and that’s revolutionary.
Explore Further:
- NIPs Directory - Protocol specifications
- Client Directory - Try different implementations
- Relay Directory - Find relays to connect to
- For Developers - Build on Nostr
Ready to Get Started?
- Getting Started Guide - Join Nostr today
- Security Best Practices - Protect your identity