Tables
This page documents all tables in the BigBrotr database schema.
relays
Section titled “relays”Registry of known Nostr relay URLs.
CREATE TABLE relays ( url TEXT PRIMARY KEY, network TEXT NOT NULL, inserted_at BIGINT NOT NULL);| Column | Type | Description |
|---|---|---|
url | TEXT | WebSocket URL (primary key) |
network | TEXT | ’clearnet’ or ‘tor’ |
inserted_at | BIGINT | Unix timestamp when discovered |
Example Queries
Section titled “Example Queries”-- Count by network typeSELECT network, COUNT(*) FROM relays GROUP BY network;
-- Recently discovered relaysSELECT url, TO_TIMESTAMP(inserted_at) as discoveredFROM relaysORDER BY inserted_at DESCLIMIT 20;
-- Tor relaysSELECT url FROM relays WHERE network = 'tor';events
Section titled “events”Nostr events with efficient BYTEA storage.
BigBrotr Schema (Full)
Section titled “BigBrotr Schema (Full)”CREATE TABLE events ( id BYTEA PRIMARY KEY, pubkey BYTEA NOT NULL, created_at BIGINT NOT NULL, kind INTEGER NOT NULL, tags JSONB NOT NULL, tagvalues TEXT[] GENERATED ALWAYS AS (tags_to_tagvalues(tags)) STORED, content TEXT NOT NULL, sig BYTEA NOT NULL);LilBrotr Schema (Essential Metadata)
Section titled “LilBrotr Schema (Essential Metadata)”CREATE TABLE events ( id BYTEA PRIMARY KEY, pubkey BYTEA NOT NULL, created_at BIGINT NOT NULL, kind INTEGER NOT NULL, sig BYTEA NOT NULL);| Column | Type | Description | LilBrotr |
|---|---|---|---|
id | BYTEA | Event ID (32 bytes) | ✓ |
pubkey | BYTEA | Author’s public key (32 bytes) | ✓ |
created_at | BIGINT | Unix timestamp | ✓ |
kind | INTEGER | Event kind (NIP-01) | ✓ |
tags | JSONB | Event tags array | ✗ (omitted) |
tagvalues | TEXT[] | Generated searchable values | ✗ (omitted) |
content | TEXT | Event content | ✗ (omitted) |
sig | BYTEA | Schnorr signature (64 bytes) | ✓ |
LilBrotr indexes all events but omits the heavy tags and content fields. Queries by author, kind, timestamp, and relay distribution work identically in both implementations.
Example Queries
Section titled “Example Queries”-- Recent eventsSELECT encode(id, 'hex') as event_id, kind, TO_TIMESTAMP(created_at) as createdFROM eventsORDER BY created_at DESCLIMIT 20;
-- Events by kindSELECT kind, COUNT(*) as countFROM eventsGROUP BY kindORDER BY count DESC;
-- Events by authorSELECT encode(pubkey, 'hex') as author, COUNT(*) as event_countFROM eventsGROUP BY pubkeyORDER BY event_count DESCLIMIT 20;
-- Search by tag (BigBrotr only)SELECT encode(id, 'hex') as event_idFROM eventsWHERE tagvalues @> ARRAY['p:79be667ef9dcbbac...'];tagvalues Column
Section titled “tagvalues Column”The tagvalues column is auto-generated for efficient tag searching:
-- Tags: [["p", "abc123"], ["e", "def456"]]-- Generates: ["p:abc123", "e:def456"]
-- Search events mentioning a pubkeySELECT * FROM eventsWHERE tagvalues @> ARRAY['p:79be667ef9dcbbac...'];
-- Search events referencing another eventSELECT * FROM eventsWHERE tagvalues @> ARRAY['e:abc123def456...'];events_relays
Section titled “events_relays”Junction table tracking which relays have each event.
CREATE TABLE events_relays ( event_id BYTEA NOT NULL REFERENCES events(id), relay_url TEXT NOT NULL REFERENCES relays(url), seen_at BIGINT NOT NULL, PRIMARY KEY (event_id, relay_url));| Column | Type | Description |
|---|---|---|
event_id | BYTEA | Foreign key to events |
relay_url | TEXT | Foreign key to relays |
seen_at | BIGINT | When event was seen on this relay |
Example Queries
Section titled “Example Queries”-- Relays hosting an eventSELECT relay_url, TO_TIMESTAMP(seen_at) as seenFROM events_relaysWHERE event_id = decode('abc123...', 'hex');
-- Event count per relaySELECT relay_url, COUNT(*) as eventsFROM events_relaysGROUP BY relay_urlORDER BY events DESC;
-- Event redundancy (how many relays have each event)SELECT COUNT(relay_url) as relay_count, COUNT(*) as event_countFROM events_relaysGROUP BY event_idORDER BY relay_count DESC;Deduplicated NIP-11 relay information documents.
CREATE TABLE nip11 ( id BYTEA PRIMARY KEY, name TEXT, description TEXT, pubkey TEXT, contact TEXT, supported_nips JSONB, software TEXT, version TEXT, limitation JSONB, privacy_policy TEXT, terms_of_service TEXT, banner TEXT, icon TEXT, extra_fields JSONB);| Column | Type | Description |
|---|---|---|
id | BYTEA | SHA-256 hash of document |
name | TEXT | Relay name |
description | TEXT | Relay description |
pubkey | TEXT | Operator’s public key |
contact | TEXT | Contact information |
supported_nips | JSONB | Array of supported NIPs |
software | TEXT | Software name/URL |
version | TEXT | Software version |
limitation | JSONB | Relay limitations |
privacy_policy | TEXT | Privacy policy URL |
terms_of_service | TEXT | Terms of service URL |
banner | TEXT | Banner image URL |
icon | TEXT | Icon URL |
extra_fields | JSONB | Additional fields |
Example Queries
Section titled “Example Queries”-- Software distributionSELECT software, COUNT(*) as countFROM nip11WHERE software IS NOT NULLGROUP BY softwareORDER BY count DESC;
-- Relays supporting specific NIPSELECT n.name, n.softwareFROM nip11 nWHERE n.supported_nips @> '[11]';
-- Search by nameSELECT name, description, softwareFROM nip11WHERE name ILIKE '%damus%';Deduplicated NIP-66 relay test results.
CREATE TABLE nip66 ( id BYTEA PRIMARY KEY, openable BOOLEAN, readable BOOLEAN, writable BOOLEAN, rtt_open INTEGER, rtt_read INTEGER, rtt_write INTEGER);| Column | Type | Description |
|---|---|---|
id | BYTEA | SHA-256 hash of test results |
openable | BOOLEAN | Can establish connection |
readable | BOOLEAN | Responds to REQ |
writable | BOOLEAN | Accepts EVENT |
rtt_open | INTEGER | Connection latency (ms) |
rtt_read | INTEGER | Read latency (ms) |
rtt_write | INTEGER | Write latency (ms) |
Example Queries
Section titled “Example Queries”-- Capability statisticsSELECT COUNT(*) FILTER (WHERE openable) as openable, COUNT(*) FILTER (WHERE readable) as readable, COUNT(*) FILTER (WHERE writable) as writableFROM nip66;
-- Average RTTSELECT AVG(rtt_open) as avg_open, AVG(rtt_read) as avg_read, AVG(rtt_write) as avg_writeFROM nip66WHERE openable = true;relay_metadata
Section titled “relay_metadata”Time-series snapshots of relay health and metadata.
CREATE TABLE relay_metadata ( relay_url TEXT NOT NULL REFERENCES relays(url), generated_at BIGINT NOT NULL, nip11_id BYTEA REFERENCES nip11(id), nip66_id BYTEA REFERENCES nip66(id), PRIMARY KEY (relay_url, generated_at));| Column | Type | Description |
|---|---|---|
relay_url | TEXT | Foreign key to relays |
generated_at | BIGINT | Snapshot timestamp |
nip11_id | BYTEA | Foreign key to nip11 |
nip66_id | BYTEA | Foreign key to nip66 |
Example Queries
Section titled “Example Queries”-- Latest metadata for a relaySELECT rm.relay_url, TO_TIMESTAMP(rm.generated_at) as checked, n11.name, n66.openable, n66.readableFROM relay_metadata rmLEFT JOIN nip11 n11 ON rm.nip11_id = n11.idLEFT JOIN nip66 n66 ON rm.nip66_id = n66.idWHERE rm.relay_url = 'wss://relay.damus.io'ORDER BY rm.generated_at DESCLIMIT 1;
-- Health history for a relaySELECT TO_TIMESTAMP(rm.generated_at) as checked, n66.openable, n66.rtt_openFROM relay_metadata rmJOIN nip66 n66 ON rm.nip66_id = n66.idWHERE rm.relay_url = 'wss://relay.damus.io'ORDER BY rm.generated_at DESCLIMIT 100;service_state
Section titled “service_state”Service state persistence for incremental processing.
CREATE TABLE service_state ( service_name TEXT PRIMARY KEY, state JSONB NOT NULL DEFAULT '{}', updated_at BIGINT NOT NULL);| Column | Type | Description |
|---|---|---|
service_name | TEXT | Service identifier |
state | JSONB | Arbitrary state data |
updated_at | BIGINT | Last update timestamp |
Example Queries
Section titled “Example Queries”-- View all service statesSELECT service_name, TO_TIMESTAMP(updated_at) as updated, stateFROM service_state;
-- Synchronizer state (per-relay timestamps)SELECT service_name, jsonb_object_keys(state->'relay_timestamps') as relay, state->'relay_timestamps'->jsonb_object_keys(state->'relay_timestamps') as last_syncFROM service_stateWHERE service_name = 'synchronizer';Next Steps
Section titled “Next Steps”- Learn about Views & Procedures
- Explore Configuration
- Check the FAQ