---
title: "Run, watch and pay for an app with erpc worker"
description: "See whether your app runs and what it costs by the hour, roll back a release, measure RPC latency from the server, back up its state and end its hourly charges."
canonical: "https://erpc.global/en/doc/erpc-cli/worker-status-and-billing/"
locale: "en"
---

# 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

```text
$ 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

| Command | What it does |
| --- | --- |
| `erpc worker logs -n 200`, `logs -f` | The app's and the agent's log. A control character in a line is printed as `?` |
| `erpc worker start` | Runs the app, sending the key when the worker is locked |
| `erpc worker stop`, `stop --lock` | Stops it; `--lock` also drops the key from memory |
| `erpc worker restart` | Stops and starts it again |
| `erpc worker releases` | The 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 list` | The 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](https://erpc.global/en/price/) and the [ERPC Web Dashboard](https://dashboard.erpc.global/en).
- **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](https://erpc.global/en/doc/erpc-cli/worker-troubleshooting/#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`.
