# Billing (/docs/environments/billing)

Managed environments are charged per second of runtime and per GB-month of kept disk from your wallet, fail-closed; your own servers are free.

| | Managed (`openstack`, `hetzner`) | Bring your own (`byo`) |
| --- | --- | --- |
| Price | Hourly rate of the size, charged per second of runtime | Free |
| While `stopped` / `archived` | €0.05 per GB-month for the kept snapshot or shelved image | — |
| To create or start | A wallet balance of at least one hour at the rate | — |
| Paid from | Your wallet (the environment owner's) | — |
| When money runs out | The machine is stopped | Nothing happens |

Inference used by an agent working in an environment is billed like any other request on your key; this page is only about compute.

## Rates [#rates]

| `size` | OpenStack (Cloudify, Romania) | Hetzner (Germany, Finland) |
| --- | --- | --- |
| `small` | 2 vCPU · 2 GB — €0.03 / h | `cx23`, 2 vCPU · 4 GB — €0.04 / h |
| `medium` | 4 vCPU · 4 GB — €0.06 / h | `cx33`, 4 vCPU · 8 GB — €0.08 / h |
| `large` | 8 vCPU · 8 GB — €0.12 / h | `cx43`, 8 vCPU · 16 GB — €0.16 / h |

Rate = vCPU × €0.01/h + GB RAM × €0.005/h of what the provider actually gives you (see [sizes](./managed.mdx#sizes)).

### GPU (preview, not enabled yet) [#gpu-preview-not-enabled-yet]

| `size` | Provider | Machine | Rate |
| --- | --- | --- | --- |
| `gpu-l4` | `gce` (Google Compute Engine, Netherlands `europe-west4`) | `g2-standard-8`: 8 vCPU · 32 GB · 1× NVIDIA L4 24 GB · 60 GB disk | €0.76 / h |

- **Spot capacity only.** Google can reclaim the GPU at any moment (preemption). The machine is then **stopped, not deleted**: your disk stays and you can start it again when capacity returns. Billing stops with it.
- **Hard 30-minute cap per run.** Every start carries a maximum run time of 30 minutes, enforced by Google itself; after it the machine stops. At most **€0.38 per run**. Start it again to continue.
- The GPU rate is fixed rather than computed from vCPU/RAM: it is the public Spot price of the machine plus its disk, converted to EUR, with a margin for Spot price changes. The formula above does not apply.
- Everything else on this page applies unchanged: per-second billing in 10-minute buckets, the one-hour balance check (€0.76), grace, budget cap, and storage for a stopped disk (60 GB — €3.00 / month).

## How a charge is computed [#how-a-charge-is-computed]

The rate is fixed when the environment is created and stored as `hourlyRateMicroEur`. The worker charges **10-minute buckets** aligned to the clock while the environment is `running`:

```text
charge (micro-EUR) = floor((hourly_rate × seconds_in_bucket + 1800) / 3600)
```

- The first bucket is partial, counted from `startedAt`; on stop or archive the last partial bucket is charged too.
- Amounts are integer micro-EUR (1 € = 1 000 000), debited from your wallet with the soonest-expiring credits first. Each bucket has a unique key (`compute:<environment>:<bucket start>`), so a retry can never charge twice.
- Ledger rows appear in the hub wallet history as **Cloud environment compute**.
- An environment stuck in `error` while its server still exists is billed like `running`, and the worker stops it after 30 minutes — a broken machine cannot keep charging you indefinitely.

## Balance check on create and start [#balance-check-on-create-and-start]

Creating a managed environment, or starting a stopped one, needs a wallet balance (of the environment owner) of at least **one hour at its rate**. Otherwise the gateway answers `402`:

```json
{
	"error": {
		"message": "Insufficient wallet balance: one hour of this machine costs 40000 micro-EUR.",
		"type": "invalid_request_error", "code": "insufficient_balance",
		"required_micro_eur": 40000, "balance_micro_eur": 12500
	}
}
```

Top up and retry. There is no exemption: compute has no free allowance to fall back on.

## Storage for stopped and archived environments [#storage-for-stopped-and-archived-environments]

A stopped or archived environment keeps its disk — a shelved image on OpenStack, a snapshot on Hetzner — and that disk costs **€0.05 per GB-month** (a month = 730 hours), charged in the same 10-minute buckets:

```text
charge (micro-EUR) = floor((GB × 50 000 × seconds_in_bucket + 1 314 000) / 2 628 000)
```

The size is the provider's image size when known, otherwise the disk of the size's server type:

| `size` | OpenStack disk | Hetzner disk |
| --- | --- | --- |
| `small` | 20 GB — €1.00 / month | 40 GB — €2.00 / month |
| `medium` | 40 GB — €2.00 / month | 80 GB — €4.00 / month |
| `large` | 80 GB — €4.00 / month | 160 GB — €8.00 / month |

Destroy the environment to stop storage charges. Storage debits share the wallet and the dedupe rule (`storage:<environment>:<bucket start>`). Unpaid storage is carried forward and collected after a top-up; your disk is never deleted for lack of funds.

## Fail-closed [#fail-closed]

A VM that keeps running on an unpaid balance is not allowed. Unlike LLM requests (which never block on a billing hiccup), compute is **fail-closed**:

| Situation | What the worker does | `stateReason` |
| --- | --- | --- |
| Balance lower than the bucket | Starts a 30-minute **grace** period (event `billing.grace`, shown with the stop time in the hub and desktop). A top-up during grace pays the missed bucket and ends it (`billing.grace_cleared`); otherwise the environment is stopped when grace ends | `insufficient_funds` |
| Three consecutive failed charges | Stops the environment | `billing_error` |
| This month's charged compute reaches the environment's budget | Stops the environment | `budget_exceeded` |

Stopped means `stop` on the provider (shelve on OpenStack, snapshot on Hetzner) — your disk is kept. Top up the wallet and **Start** the environment again.

Nothing unpaid is silently written off: every bucket that could not be charged is recorded, and the worker collects it after your next top-up, oldest first, before new buckets.

## Compute reserve [#compute-reserve]

LLM usage and compute share one wallet. Set a **compute reserve** under *Billing → Compute reserve* (€0–€1000; default €0 = off): LLM requests never spend the wallet below it, while compute may use the whole balance. When the balance above the reserve is used up, LLM requests fall back to your plan allowance or pay-as-you-go exactly as with an empty wallet.

## Budget cap [#budget-cap]

`budget_micro_eur` (set at creation; in the hub: *Monthly budget cap (€)*) is a per-environment ceiling on compute charged since the 1st of the month (UTC). Change it later on the environment page under *Budget cap*; leave it empty for no cap.

## Where to see usage [#where-to-see-usage]

- **Environment page → Cost this month**: compute charged since the 1st (UTC), billed hours, and a warning when buckets could not be charged.
- **Billing → wallet history**: every `Cloud environment compute` debit.
- **API**: each environment carries `hourlyRateMicroEur`; `GET /v1/environments/{id}` returns the last events, including state changes with their reason.

## Coming soon [#coming-soon]

Included hours per plan (the environment tracks `includedHoursUsedSeconds`, currently always charged in full) and a fiscal invoice for compute issued through brivio are not live yet.
