Run, watch and pay for an app with erpc worker

erpc worker status shows whether your app runs and what it costs by the hour. Every start shows its price first, and erpc worker delete --release-server ends the gRPC, Shreds and Unlimited RPC the app uses by the hour, then its hourly server.
This page describes ERPC CLI v0.1.0-rc.4, a pre-release.

Check an app

$ erpc worker status --env prod
api-prod on 203.0.113.10: running, release 20261101T093000Z-1a2b3c4d, pid 4217, up 2h 14m
  current 20261101T093000Z-1a2b3c4d, previous 20261028T171500Z-9f8e7d6c, 2 releases kept
  WAF: listening on port 8080, forwarding to 127.0.0.1:3000, since 2026-11-01T09:30:12Z; requests 5120, forwarded 5043, blocked 71, connections refused 12, app errors 6, addresses banned now 1
  `erpc worker delete --release-server --env prod` ends what this app is charged for.
status shows whether the app is locked or running, which release, and since when. When you are signed in, it also shows what the environment costs by the hour, each item with the price your account is charged for it, and your account's credit with how long it lasts. --json carries the same under hourly.charged.
An item that is not among the account's charges is said to be not among them, not called ended, because that list can be a minute behind a start. Without a session, or when your account's charges cannot be read, status says what is on record.

Control the app

CommandWhat it does
erpc worker logs -n 200, logs -fThe app's and the agent's log. A control character in a line is printed as ?
erpc worker startRuns the app, sending the key when the worker is locked
erpc worker stop, stop --lockStops it; --lock also drops the key from memory
erpc worker restartStops and starts it again
erpc worker releasesThe releases kept on the server (deploy.keep_releases)
erpc worker rollback, rollback --to <release>Goes back to the previous release, or the one named. Refused, with the release in use left as it was, when that release's health-check port is now another running worker's
erpc worker api <PATH>Reads the app's API from this machine, with the API still on the server's loopback (-X POST, -d '{...}' for a change)
erpc worker trades [--profit]The app's trades on its server
erpc worker listThe apps on this machine and where each is deployed; --prune drops those whose erpc.toml is gone
The app's API_TOKEN is read here and reaches the server on standard input, on no command line and in no journal. Every worker command takes --env <name> (default default) and --json, except that secret unlock and secret lock, which are about this machine's keystore and not an app, take no --env. Run from anywhere, a command finds its app by the name erpc knows it by; secret put, secret rm, key import, firewall allow and firewall deny take the app by --dir only.

How hourly charges work

  • Every start shows its price first. At a terminal, a start happens only after a yes; with --yes, the command line that names what to start is the yes.
  • An hourly product is paid from ERPC Credit, which is bought beforehand, and a start the credit does not cover is refused. Prices are on Pricing and the ERPC Web Dashboard.
  • A new VPS goes on record as soon as it is named, before it is ready. The next deploy takes it up instead of buying another.
  • For deploy, a start that got no answer is sent again, never as a new one. Its request key stays on record ([env.<name>.starting]), so running the same command again sends the same request. After some answers it stays until you remove it by hand (A purchase that erpc cannot put on record). erpc worker run keeps no record, so its next run makes a new request.
  • Deploy one environment at a time. Two deploys of the same environment started together can buy two, and that is not supported.
  • Whether a line still exists is decided by what the account is charged for. A line not billed by the hour is never ended by erpc: end it in the dashboard.

Remove an app

erpc worker delete removes the worker. erpc worker delete --release-server also ends its lines, then its hourly server. What could not be ended stays on record, and a line not billed by the hour is named, to end in the dashboard.
  • A plain delete refuses a VPS bought and never reached, since it would forget it while charged. A plain delete of a reached hourly VPS takes it off the record while it is still charged, and warns of it.
  • --forget leaves a server that can no longer be reached unreached, and --forget-line <id> takes a line ended outside erpc off the record.

Measure RPC latency from the server

erpc worker bench times RPC calls from the environment's server: ERPC's shared RPC, its Unlimited RPC, and any other side by side. The agent on the server times each call, so the numbers are what the app gets.
bash
erpc worker bench                                  # getSlot: shared RPC vs the Unlimited RPC
erpc worker bench --rounds 300 --interval 150      # for a plan that limits calls per second
erpc worker bench --url other=op://<vault-id>/<item-id>/url   # another provider's RPC
  • --method takes getSlot, getBlockHeight, getLatestBlockhash or getHealth.
  • --no-shared leaves the shared RPC out. A --url value may be the URL itself, an op://…, keychain:… or keystore:… reference (where a URL with a key in it is kept; never the trading key's entry, which is refused), or - (read from standard input, or asked for unseen). More than six endpoints are refused.
  • The bench prints p50, p90, p99, min and max, failures with the first reason, and how many slots each answer was behind the freshest in the same round.
  • Keys reach the server on standard input only, and the table shows scheme, host and port.

Back up the app's state

erpc worker backup on backs the app's state up every day to ERPC Global Storage, encrypted by restic, at --at in the server's time and within 30 minutes after. A storage plan is needed (erpc storage buy 5).
  • What is backed up is the app's state, /var/lib/private/erpc-worker-<id>. The releases are not, since a deploy puts them back. Redis and PostgreSQL data are not covered.
  • The server cannot delete snapshots. It never holds the erpc session, the account's admin key or its master password.
  • A server taken over can read every machine's snapshots in the account, this machine's included; keep the repository's key, which restic never changes, after off; add snapshots under another machine's name, so check what restore latest picks after one; and fill the account's storage, which stops every machine's backups. erpc worker backup off revokes the server's access key first, whether or not the server answers.
  • restic copies files as they are while the worker runs, so a database may need its own dump to restore consistent. A run missed while the server was off runs when it is back.
  • erpc worker backup off, status and now stop, report on and run the backup. The snapshots stay after off, and erpc backup prune --host thins out old ones.
Restore from this machine, after erpc backup init on it:
bash
erpc backup restore latest --from-host erpc-worker-<id>-<tag> --path /var/lib/private/erpc-worker-<id> --target ./restored

Several environments and machines

  • Several workers on one server each run as their own unit, share the server's firewall table, and each opens only its own port.
  • One app can have several environments ([env.staging], [env.prod]), each with its own server and lines.
  • An environment can keep its server facts in 1Password instead of erpc.toml. Then any machine signed in to that vault, with the app's repository, can run every command; keychain: and keystore: references in such an app are warned about, since another machine cannot read them. A new environment keeps its facts in 1Password when erpc login keeps the session there; deploy --vault <vault-id> names another vault, and deploy --inline keeps the facts in erpc.toml.