GenerateSaaS

Always-on companions

Run the companion on a VPS or always-on machine so scheduled runs never wait, and understand what happens when a device is offline.

The companion polls your backend from wherever it runs - pairing works from any machine that can reach your app's URL. A laptop that sleeps means queued work waits; an always-on machine means schedules run the moment they are due.

What happens while a device is offline

  • A run dispatched to an offline device queues for 24 hours and starts as soon as the device reconnects.
  • A schedule that comes due again while its previous run is still queued replaces it - only the latest run executes on reconnect, never a backlog.
  • A run that is never collected inside the window surfaces as expired in the app (the chat view and the schedule's status both say so).
  • The schedule card shows its pinned device and warns while that device is offline; if another paired device is online you can move the schedule to it in one click.

Run it on an always-on machine

Install on the server

Run the same install one-liner from the app's Companions page on the VPS (Linux and macOS are supported; a small always-free cloud instance is plenty - the companion is idle until work arrives).

Pair it from the server

Pair exactly as on a desktop: run the pair command from the Companions page and approve it in your browser. Pairing binds the DEVICE, so the server shows up as its own companion alongside any others.

Let the service keep it alive

The install one-liner's setup registers the always-on OS service for you, so the daemon starts on boot and survives reboots. It polls quietly when idle and speeds up by itself while runs are active or the app is open - no tuning needed.

One daemon, every surface

One daemon serves everything on its machine. When the desktop app also runs there, the always-on service picks up the on-device config the app stages and serves the app's local drive too - live, within a reconcile tick, no restart. The app then attaches to the running service instead of starting a second daemon, and its local runs share the same machine-global cap below.

Tuning

  • Concurrent runs: the cap is machine-global - one budget across every surface the daemon serves (all paired backends plus the desktop app's local drive), not a per-backend limit. It defaults to 2; raise it on a beefy server with limits set --max-concurrent-runs 4 (takes effect within a poll, no restart). Interactive local work keeps priority: a live chat runs at once and background or dispatched runs throttle around it - so under a low cap, sustained local chat can delay backend runs.
  • Poll cadence: the backend adapts it automatically - about 1s while runs are active, 5s while the app is open, and the configured idle cadence otherwise. There is nothing to configure on the device. See poll cadence and request budgets.

On this page