Beszel — Lightweight Server Monitoring
Hub-and-agent monitoring that uses just 23 MB of RAM per server. Deploy in minutes, monitor your entire fleet from a single dashboard.
RamNode VPS (any plan), Docker & Docker Compose, SSH access
25–35 minutes
$4/mo (512 MB) for hub; agents on any plan
Most monitoring tools ask you to choose between two bad options: pay for a SaaS dashboard that phones home all your server metrics, or run a full observability stack that consumes more resources than the apps you're trying to monitor. Beszel is a third option.
Beszel is an open-source monitoring platform built around a hub-and-agent model. The hub runs on one server and provides the dashboard; lightweight agents run on every server you want to monitor and report back to the hub. The entire agent process uses roughly 23 MB of RAM at idle. On a $4/month RamNode VPS with 512 MB of RAM, that leaves you with nearly all of it for your actual workloads.
What Beszel Monitors
- • System metrics — CPU usage, memory, disk I/O, network throughput
- • Per-container metrics — Docker and Podman container stats without additional exporters
- • Historical data — Retention configurable from 1 day to indefinite, stored in an embedded SQLite database
- • Multi-server overview — All your servers visible in a single dashboard pane
- • Alerting — CPU, memory, disk, and network thresholds with notifications via ntfy, Gotify, Slack, Discord, Pushover, Telegram, and email
What it does not do: application-level tracing, log aggregation, or distributed tracing. Those use cases are covered later in this series. Beszel is intentionally scoped to host-level and container-level metrics.
Architecture Overview
RamNode VPS A (hub server)
└── Beszel Hub (Docker container)
└── Web UI + API
RamNode VPS B, C, D... (monitored servers)
└── Beszel Agent (single binary, ~23 MB RAM)
└── Reports metrics → Hub over SSH tunnelThe agent does not open a port on the monitored server. It communicates outbound to the hub over an encrypted SSH connection. This means you do not need to open additional firewall rules on your monitored servers — only the hub needs to be reachable.
Deploy the Hub
Step 1 — Create the project directory
mkdir -p /opt/beszel && cd /opt/beszelStep 2 — Write the Compose file
services:
beszel:
image: henrygd/beszel:latest
container_name: beszel
restart: unless-stopped
ports:
- "8090:8090"
volumes:
- ./beszel-data:/beszel_dataStep 3 — Start the hub
docker compose up -dStep 4 — Create your admin account
Open http://YOUR_SERVER_IP:8090 in a browser. On first load, Beszel prompts you to create an admin account. Do this immediately — the registration endpoint is open until you create the first user.
Set a strong password. There is no second factor by default, so treat this password as you would a root password.
Step 5 — Secure with a reverse proxy (recommended)
If you are running Caddy:
beszel.yourdomain.com {
reverse_proxy localhost:8090
}If you are running nginx:
server {
listen 443 ssl;
server_name beszel.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/beszel.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/beszel.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8090;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}After this step, close port 8090 in your firewall and route everything through the reverse proxy.
Add the Hub Server as Its Own Agent
The hub server should monitor itself. In the Beszel dashboard, click Add System. You will be shown a public key to authorize and the agent installation command.
For the hub server itself, use the Docker-based agent:
beszel-agent:
image: henrygd/beszel-agent:latest
container_name: beszel-agent
restart: unless-stopped
network_mode: host
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
PORT: 45876
KEY: "PASTE_YOUR_PUBLIC_KEY_HERE"The KEY value comes from the dashboard when you click Add System. Restart the stack:
docker compose up -dBack in the dashboard, finish adding the system using localhost as the hostname and 45876 as the port.
Add Remote Agents to Additional Servers
For every other VPS you want to monitor, the agent runs as a standalone binary rather than Docker. This keeps the footprint smaller.
Step 1 — Install the agent
In the Beszel dashboard, click Add System again. Copy the SSH public key displayed. Then on the remote server:
curl -sL https://raw.githubusercontent.com/henrygd/beszel/main/supplemental/scripts/install-agent.sh \
-o /tmp/install-agent.sh && chmod +x /tmp/install-agent.shRun it with your public key and desired port:
/tmp/install-agent.sh -p 45876 -k "PASTE_PUBLIC_KEY_HERE"This installs the agent binary to /opt/beszel-agent/, creates a systemd service, and starts it automatically.
Step 2 — Verify the agent
systemctl status beszel-agentStep 3 — Add the system in the dashboard
Complete the Add System form with a descriptive name (e.g., "ramnode-nyc-prod-01"), the public IP, and port 45876. Within a few seconds, metrics should start appearing.
Monitor Docker Containers
If the server running the agent also runs Docker containers, Beszel automatically picks them up. No additional configuration is needed. In the system detail view, switch to the Containers tab to see per-container CPU, memory, and network stats.
For the binary agent, add the agent user to the docker group if needed:
usermod -aG docker beszel-agent
systemctl restart beszel-agentConfigure Alerts
Beszel's alerting is configured per-system and per-metric. In the dashboard, click the bell icon on any system.
Available alert triggers
| Metric | Threshold type |
|---|---|
| CPU usage | Percentage, sustained duration |
| Memory usage | Percentage |
| Disk usage | Percentage |
| Network I/O | Bytes per second |
| System offline | Binary (up/down) |
Notification channels
Go to Settings > Notifications to add a channel. Beszel supports ntfy, Gotify, Slack, Discord, Pushover, Telegram, and email.
For a RamNode fleet, a Discord webhook is the quickest path to working alerts:
- In your Discord server, go to Channel Settings > Integrations > Webhooks
- Create a new webhook and copy the URL
- In Beszel Settings > Notifications, select Discord and paste the URL
- Save and click Test to verify delivery
Recommended alert thresholds
| Alert | Threshold | Notes |
|---|---|---|
| CPU | 90% for 5 min | Sustained high CPU usually indicates a problem |
| Memory | 85% | Leave headroom for bursts |
| Disk | 80% | At 80% you still have time to act |
| System offline | Immediate | Non-negotiable |
Firewall Considerations
The hub needs to reach port 45876 on each agent server. If your agents are behind UFW:
ufw allow from HUB_IP to any port 45876If you prefer to keep things locked down further, Tailscale or WireGuard between hub and agents is a solid option — Beszel works fine over a private mesh network.
Keeping Beszel Updated
The hub image follows latest by default. To update:
cd /opt/beszel
docker compose pull
docker compose up -dFor the binary agent:
curl -sL https://raw.githubusercontent.com/henrygd/beszel/main/supplemental/scripts/install-agent.sh \
-o /tmp/install-agent.sh && chmod +x /tmp/install-agent.sh
/tmp/install-agent.sh -p 45876 -k "YOUR_KEY"The install script handles updating in-place.
Resource Usage Benchmark
On a RamNode VPS running the hub with 3 agents reporting in:
| Component | RAM | CPU (idle) |
|---|---|---|
| Beszel hub container | ~45 MB | <0.1% |
| Beszel agent (per server) | ~23 MB | <0.1% |
| SQLite data (30-day, 3 servers) | ~12 MB disk | — |
This makes Beszel viable even on the smallest RamNode plans. You can dedicate one low-cost VPS as your monitoring hub and agents on your production servers will barely register in your resource accounting.
What's Next
Beszel gives you continuous visibility into what your servers are doing right now and historically. What it does not give you is external uptime monitoring — the ability to check whether your services are reachable from the outside world.
Part 2 covers:
- HTTP, TCP, DNS, and certificate expiry monitoring
- Push/heartbeat monitors for cron jobs and background workers
- Public status pages with custom domains
- Maintenance windows for planned reboots
