Documentation · PeerWeave

Keep-warm operator notes

Source of truth is the PeerWeave repo: deploy/keep-warm/. This page is the public copy so the job can be found from lucastilford.com without opening Git.

What this is

A systemd user timer on an always-on Linux box that GETs PeerWeave so Render Free does not idle-spin-down the origin.

Render Free web services spin down after 15 minutes with no inbound HTTP. Keep-warm is the workaround. Starter does not idle — that is the lasting fix. A Free instance kept awake uses most of the 750 monthly instance hours.

This is not manticore-net. That project is a local packet sensor for networks you own. Keep-warm does not capture packets and does not send credentials.

Narrative: Keeping PeerWeave awake. lucastilford.com itself is a Render static site (empty build, repo root = publish directory) and does not need this job.

What it hits

Identified User-Agent, no body, no credentials. Default GETs:

  • https://www.peerweave.com/ — visitor landing page
  • https://www.peerweave.com/app — web client
  • https://peer-weave.onrender.com/ — Render origin (bypasses a future CDN HIT that would skip the process that sleeps)

If the body looks like Render’s wake-up interstitial (SERVICE WAKING UP, APPLICATION LOADING, and kin), the script retries with exponential backoff until PeerWeave / Next.js HTML arrives. Per-request ceiling is 90 seconds. Success is HTTP 2xx/3xx.

Hub PC (primary)

GitHub’s schedule cron can delay past 15 minutes. A systemd user timer on an always-on machine is the reliable path. Linger is enabled when passwordless sudo is available (loginctl enable-linger), so the timer keeps firing after logout.

chmod +x deploy/keep-warm/*.sh
./deploy/keep-warm/install.sh

systemctl --user status peerweave-keep-warm.timer
journalctl --user -u peerweave-keep-warm.service -n 50
peerweave-keep-warm --once

systemctl --user disable --now peerweave-keep-warm.timer

One-shot / loop without systemd:

./deploy/keep-warm/keep-warm.sh --once
./deploy/keep-warm/keep-warm.sh --loop

Install copies the script to ~/.local/bin/peerweave-keep-warm, units to ~/.config/systemd/user/, and an optional env file to ~/.peerweave/keep-warm.env if missing.

Interval

Knob Value Why
Timer 10 minutes + up to 45s jitter Under the 15-minute idle window, not a hammer
Script floor 5 minutes --loop / PW_KEEPWARM_INTERVAL_SEC cannot go faster
Request timeout 90 seconds Covers a cold start if one sneaks through
OnBootSec 45 seconds First ping shortly after boot / login
Persistent true Catch a missed tick after downtime

Environment

Optional file: ~/.peerweave/keep-warm.env (systemd EnvironmentFile: no quotes, no export).

Variable Default Purpose
PW_KEEPWARM_URLS the three URLs above Space-separated GET targets
PW_KEEPWARM_INTERVAL_SEC 600 Loop sleep only. Floor 300.
PW_KEEPWARM_UA PeerWeave-KeepWarm/1.0 (+https://github.com/Lucastil2212/peer-weave) Identified User-Agent
PW_KEEPWARM_MAX_TIME 90 Per-request ceiling (seconds)
PEERWEAVE_SKIP_SYSTEMD 0 Install binary only
PEERWEAVE_KEEPWARM_ENABLE 1 0 = install units but do not start the timer

GitHub Actions (backup)

.github/workflows/keep-warm.yml runs every 10 minutes on main and on workflow_dispatch. It sparse-checkouts deploy/keep-warm and runs keep-warm.sh --once. Treat it as a spare heart, not the only one. It only helps after that workflow is on the default branch.

If visitors still see the boot page

  1. Confirm the live Render service is Free, not Starter.
  2. systemctl --user status peerweave-keep-warm.timer — enabled, next elapse under 15 minutes.
  3. journalctl --user -u peerweave-keep-warm.service -n 50 — look for OK vs WAKE / FAIL.
  4. Manual: peerweave-keep-warm --once.
  5. Upgrade the Render web service to Starter if the site should stay up without a ping.
Read the log PeerWeave hub peer-weave on GitHub