Implementations
BigBrotr’s three-layer architecture enables multiple deployment configurations from the same codebase. Two implementations are provided out of the box, each optimized for different use cases.
Available Implementations
Section titled “Available Implementations”BigBrotr (Full-Featured)
Section titled “BigBrotr (Full-Featured)”The default implementation with complete event storage and all features enabled.
| Feature | Value |
|---|---|
| Event Storage | Full (tags, content, signatures) |
| Tor Support | Enabled |
| Concurrency | 10 parallel connections, 10 worker processes |
| PostgreSQL Port | 5432 |
| PGBouncer Port | 6432 |
| Tor Port | 9050 |
Best for:
- Complete Nostr archiving
- Research and analytics requiring full event data
- Applications needing tag-based queries
- Long-term event preservation
cd implementations/bigbrotrdocker-compose up -dLilBrotr (Lightweight)
Section titled “LilBrotr (Lightweight)”A lightweight implementation that indexes all events but omits storage-heavy fields (tags, content) to minimize disk usage.
| Feature | Value |
|---|---|
| Event Storage | Essential metadata (id, pubkey, created_at, kind, sig) |
| Omitted Fields | tags, tagvalues, content |
| Disk Savings | ~60% compared to BigBrotr |
| Tor Support | Disabled by default |
| Concurrency | 5 parallel connections |
| PostgreSQL Port | 5433 |
| PGBouncer Port | 6433 |
| Tor Port | 9051 |
Best for:
- Event indexing without content storage
- Analytics on event metadata (authors, kinds, timestamps)
- Resource-constrained environments
- When you don’t need tag-based queries or event content
- Running alongside BigBrotr on the same machine
cd implementations/lilbrotrdocker-compose up -dSchema Differences
Section titled “Schema Differences”The key difference is in the events table:
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, -- Stored tagvalues TEXT[] GENERATED ALWAYS AS (tags_to_tagvalues(tags)) STORED, -- Indexed for queries content TEXT NOT NULL, -- Stored sig BYTEA NOT NULL);LilBrotr Schema (Lightweight)
Section titled “LilBrotr Schema (Lightweight)”CREATE TABLE events ( id BYTEA PRIMARY KEY, pubkey BYTEA NOT NULL, created_at BIGINT NOT NULL, kind INTEGER NOT NULL, -- tags NOT stored (saves ~40% disk space) -- tagvalues NOT generated (no tag-based queries) -- content NOT stored (saves ~20% disk space) sig BYTEA NOT NULL);LilBrotr still indexes all events from all relays - it simply stores less data per event. You can still query by author, kind, timestamp, and track event distribution across relays.
Running Both Simultaneously
Section titled “Running Both Simultaneously”Both implementations can run on the same machine using different ports:
# Start BigBrotrcd implementations/bigbrotrdocker-compose up -d
# Start LilBrotr (in another terminal)cd implementations/lilbrotrdocker-compose up -dAccess databases:
# BigBrotrpsql -h localhost -p 5432 -U admin -d bigbrotr
# LilBrotrpsql -h localhost -p 5433 -U admin -d lilbrotrCreating Custom Implementations
Section titled “Creating Custom Implementations”You can create your own implementation for specific use cases:
Step 1: Copy an Existing Implementation
Section titled “Step 1: Copy an Existing Implementation”cp -r implementations/bigbrotr implementations/myimplcd implementations/myimplStep 2: Customize Configuration
Section titled “Step 2: Customize Configuration”Edit YAML files in yaml/ directory:
tor: enabled: false # Disable Tor
filter: kinds: [0, 1, 3, 6, 7] # Only sync specific event kinds
concurrency: max_parallel: 3 # Lower concurrency max_processes: 2 # Fewer workersStep 3: Modify SQL Schema (Optional)
Section titled “Step 3: Modify SQL Schema (Optional)”Edit postgres/init/02_tables.sql for custom storage:
-- Only store metadata events (kinds 0, 3, 10002)ALTER TABLE events ADD CONSTRAINT events_kind_check CHECK (kind IN (0, 3, 10002));Step 4: Update Docker Compose Ports
Section titled “Step 4: Update Docker Compose Ports”Edit docker-compose.yaml to avoid port conflicts:
services: postgres: ports: - "5434:5432" # Different port pgbouncer: ports: - "6434:5432"Step 5: Deploy
Section titled “Step 5: Deploy”cp .env.example .envnano .env # Set DB_PASSWORDdocker-compose up -dCommon Customization Scenarios
Section titled “Common Customization Scenarios”Archive-Only (Specific Event Kinds)
Section titled “Archive-Only (Specific Event Kinds)”Store only specific event types like profiles and contact lists:
filter: kinds: [0, 3, 10002] # Profile, contacts, relay listSingle-Relay Monitor
Section titled “Single-Relay Monitor”Monitor and sync from a single relay:
source: from_database: false static_relays: - "wss://relay.damus.io"Metrics-Only (No Events)
Section titled “Metrics-Only (No Events)”Store only relay metadata, no events:
-- postgres/init/02_tables.sql-- Remove or empty the events table-- Keep only relays, relay_metadata, nip11, nip66Regional Deployment
Section titled “Regional Deployment”Use region-specific seed relays:
wss://relay.example.euwss://relay.example.dewss://relay.example.frImplementation Structure
Section titled “Implementation Structure”Each implementation contains:
implementations/myimpl/├── yaml/│ ├── core/│ │ └── brotr.yaml # Database connection settings│ └── services/│ ├── initializer.yaml # Schema verification, seed file│ ├── finder.yaml # API sources, intervals│ ├── monitor.yaml # Health check settings│ └── synchronizer.yaml # Event sync configuration├── postgres/│ └── init/ # SQL schema files (00-99)│ ├── 01_extensions.sql│ ├── 02_tables.sql│ ├── 03_indexes.sql│ ├── 04_functions.sql│ └── 05_views.sql├── pgbouncer/│ └── pgbouncer.ini # Connection pooler config├── data/│ └── seed_relays.txt # Initial relay URLs├── docker-compose.yaml├── Dockerfile└── .env.exampleThe core (src/core/) and service (src/services/) layers remain unchanged across all implementations. Only configuration differs.
Next Steps
Section titled “Next Steps”- Learn about the Architecture
- Explore Configuration options
- Understand Service behavior