Back to articles
Technology Insight

Scaling Decentered Infrastructure: How to Build a High-Performance Nostr Relay Using Rust on a Minimalist 1-vCPU VPS

June 5, 2026

Introduction to Nostr and the Relay Architecture

The landscape of social media and data distribution is undergoing a profound paradigm shift. Centralized platforms, once the undisputed gatekeepers of digital discourse, are increasingly scrutinized for algorithmic bias, data privacy breaches, and arbitrary censorship. In response to these vulnerabilities, open-source protocols have emerged to decentralize the web. Among the most promising is Nostr (Notes and Other Stuff Transmitted by Relays), a minimalist, censorship-resistant protocol designed for global, decentralized cryptographic communication.

Unlike traditional networks that rely on centralized databases, Nostr operates via a simple architecture consisting of two primary components: clients and relays. Clients are the user interfaces that generate, sign, and display data, while relays are backend servers responsible for receiving, storing, and distributing these cryptographic events to connected clients. Because relays do not communicate with each other—clients connect to multiple relays simultaneously—the resilience of the entire ecosystem rests on the proliferation of independent, self-hosted relays.

A common misconception among infrastructure engineers is that hosting a robust data hub requires expensive, multi-core cloud instances. However, by selecting a highly optimized technology stack, it is entirely feasible to operate a high-throughput Nostr relay on a cost-effective, entry-level Virtual Private Server (VPS) equipped with just 1 vCPU and 1 GB of RAM. This guide provides a comprehensive blueprint for building, optimizing, and deploying a self-hosted Nostr relay using Rust, a systems programming language celebrated for its fearless concurrency and minimal resource footprint.

Why Rust is the Ultimate Choice for Minimalist Infrastructure

When engineering for highly constrained environments like a 1-vCPU VPS, software efficiency is not merely a preference—it is a strict technical constraint. Traditional interpreted languages or runtime-heavy environments (such as Node.js, Python, or even Java) introduce significant overhead through garbage collection, heavy memory footprints, and suboptimal CPU utilization. Under a sudden influx of WebSocket connections, these runtimes can quickly exhaust available RAM, triggering the Linux OOM (Out of Memory) killer or causing severe latency spikes.Rust eliminates these operational risks through several core architectural advantages:

  • Zero-Cost Abstractions: Rust compiles directly to machine code, ensuring that high-level abstractions do not introduce runtime performance penalties.
  • No Garbage Collector: By utilizing a strict ownership and lifetime model, Rust manages memory at compile time. This results in incredibly low, predictable memory usage, often keeping idle relay operations under 50 MB of RAM.
  • Asynchronous Concurrency with Tokio: The tokio runtime allows Rust applications to handle tens of thousands of concurrent WebSocket connections efficiently using a small number of OS threads, making it perfectly suited for a single-core CPU architecture.

By leveraging an established, production-grade Rust implementation such as nostr-rs-relay or wrdn, administrators can maximize hardware utility, ensuring that every cycle of the 1-vCPU is dedicated to processing cryptographic events rather than managing runtime overhead.

Prerequisites and Environment Setup

Before initiating the installation process, ensure you have provisioned a clean VPS from a reputable cloud provider (such as DigitalOcean, Linode, or Hetzner). The absolute minimum recommended specifications for this deployment are:

  • CPU: 1 vCPU (Shared or Dedicated)
  • RAM: 1 GB (with a swap file configured for safety)
  • Storage: 20 GB+ SSD or NVMe (depending on your desired retention policy)
  • OS: Ubuntu 22.04 LTS or Debian 12

Step 1: System Update and Security Baseline

Log in to your VPS via SSH and execute the following commands to update the system packages and install essential build dependencies:

sudo apt update && sudo apt upgrade -y
sudo apt install -y build-essential libssl-dev pkg-config git curl ufw git

Next, configure a basic firewall to secure your server, ensuring that only necessary ports are accessible:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable

Step 2: Configuring Virtual Memory (Swap)

On a 1 GB RAM instance, a sudden burst of concurrent connections or database indexing could exhaust physical memory. Creating a swap file acts as a critical safety net:

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Compiling and Configuring the Rust Nostr Relay

With the environment prepared, we will install the Rust toolchain and compile nostr-rs-relay, a widely respected, highly performant relay implementation optimized for SQLite and PostgreSQL backends. For our resource-constrained setup, we will utilize SQLite due to its near-zero configuration and low idle memory usage.

Step 1: Install Rustup

Install the official Rust compiler and cargo package manager using the official script:

curl --proto '=https' --tlsv1.2 -sSf [https://sh.rustup.rs](https://sh.rustup.rs) | sh -s -- -y
source $HOME/.cargo/env

Step 2: Clone and Build the Source Code

Clone the repository and compile the binary with the release profile to enable compiler optimizations:

git clone [https://github.com/scottsilver/nostr-rs-relay.git](https://github.com/scottsilver/nostr-rs-relay.git)
cd nostr-rs-relay
cargo build --release

The compilation process may take several minutes on a single-core machine. Once completed, the optimized binary will be located at target/release/nostr-rs-relay. Move this binary to a global system path for easier management:

sudo cp target/release/nostr-rs-relay /usr/local/bin/

Step 3: Configuration Optimization

Create a directory for the configuration file and database storage:

sudo mkdir -p /etc/nostr-rs-relay
sudo mkdir -p /var/lib/nostr-rs-relay

Copy the default configuration file and open it for editing. To protect your 1-vCPU VPS from malicious actors or spam exhaustion, you must configure strict limits within config.toml:

Crucial Optimization Tip: Restrict the maximum event size and implement aggressive rate limiting to prevent malicious clients from overloading the CPU with complex database queries.

Modify the following parameters in your config.toml:

  • [database]: Set the path to /var/lib/nostr-rs-relay/nostr.db.
  • [network]: Bind the application to 127.0.0.1:8080 (we will use Nginx as a reverse proxy).
  • [limits]: Set max_event_bytes to 65536 (64 KB) and limit maximum subscriptions per websocket to 20.

Deploying Nginx and Securing Connections via SSL

Nostr clients connect to relays using secure WebSockets (wss://). To handle SSL termination efficiently and route traffic to our Rust application, we will deploy Nginx alongside Certbot for automated Let's Encrypt certificates.

Step 1: Install and Configure Nginx

Install Nginx using the package manager:

sudo apt install -y nginx

Create a new Nginx configuration file for your relay domain (e.g., relay.yourdomain.com):

sudo nano /etc/nginx/sites-available/nostr-relay

Insert the following configuration to handle WebSocket upgrading and proxy traffic to port 8080:

server {
    listen 80;
    server_name relay.yourdomain.com;

    location / {
        proxy_pass [http://127.0.0.1:8080](http://127.0.0.1:8080);
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    
        # Extended timeouts for persistent WebSocket connections
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
    }
}

Enable the site configuration and restart Nginx:

sudo ln -s /etc/nginx/sites-available/nostr-relay /etc/nginx/sites-enabled/
sudo systemctl restart nginx

Step 2: Obtain an SSL Certificate

Automate SSL provision using Certbot:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d relay.yourdomain.com

Certbot will automatically modify the Nginx configuration to enforce HTTPS and set up secure WebSocket routing.

Ensuring High Availability with Systemd

To ensure that the Nostr relay automatically starts up upon system boot and recovers gracefully from unexpected crashes, we will wrap the execution binary in a systemd service container.

Create the service file:

sudo nano /etc/systemd/system/nostr-relay.service

Populate it with the following configuration, ensuring it runs under a secure, non-root user context:

[Unit]
Description=Nostr Rust Relay
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/lib/nostr-rs-relay
ExecStart=/usr/local/bin/nostr-rs-relay --config /etc/nostr-rs-relay/config.toml
Restart=always
RestartSec=5

# Resource limits to safeguard the 1-vCPU VPS
MemoryMax=750M
CPUQuota=85%

[Install]
WantedBy=multi-user.target

Reload the systemd daemon, enable the service, and start your new relay:

sudo systemctl daemon-reload
sudo systemctl enable nostr-relay
sudo systemctl start nostr-relay

Verify that your relay is running smoothly by checking the system logs:

sudo journalctl -u nostr-relay -f -n 50

Performance Tuning and Resource Maintenance

Operating public-facing infrastructure on restricted hardware requires proactive maintenance. Implement the following best practices to keep your 1-vCPU Rust relay running at peak performance indefinitely:

  1. Database Vacuuming: Over time, SQLite databases accumulate fragmented pages. Set up a weekly cron job to execute a VACUUM; command to compress storage and rebuild search indexes.
  2. Event Retention Policies: Edit your config.toml to automatically delete ephemeral events (such as typing indicators or high-frequency reactions) after a designated period (e.g., 30 days) to prevent disk saturation.
  3. Monitoring Tools: Utilize lightweight utilities like htop and ncdu to monitor real-time CPU threads and disk usage without consuming excessive system resources.

Conclusion

By marrying the lean, memory-safe architecture of Rust with strategic server-side optimizations, deploying a resilient, high-performance Nostr relay on a single-core VPS is not only possible—it is highly efficient. This minimalist deployment proves that entering the frontier of decentralized infrastructure does not require capital-intensive cloud architectures. As an independent relay operator, you are now actively contributing to the robustness, censorship resistance, and democratization of global communications. Test your connection by plugging your new domain into any standard Nostr client, and welcome to the future of open-source data routing.