# MicroVM runners

Let CodeHerder launch its own short-lived AWS devices automatically when your workspace's queue outruns your fleet.

Source: https://codeherder.com/docs/microvm-runners/

Let CodeHerder launch its own short-lived AWS devices automatically when your workspace's queue outruns your fleet.

A **MicroVM runner** is a device CodeHerder launches for you, in your own AWS account, only when it’s needed. Turn it on, and CodeHerder watches your workspace’s queue: when work is waiting with nowhere to run, it starts a microVM. The microVM registers itself as a device, picks up work, and goes away again once it’s no longer needed.

This is the automatic sibling of [Launch a device on AWS](https://codeherder.com/docs/launch-a-device-on-aws/), which launches one EC2 device the moment you click a button. A runner launches itself, repeatedly, whenever your fleet falls short — no click required.

## Turn it on

Open **Settings → General** and find the **MicroVM Runner** card. A workspace owner or admin can edit every field there; everyone else sees the same values read-only.

| Field | Where it applies | How it inherits |
| --- | --- | --- |
| Launch microVM runners when this workspace’s queue exceeds capacity | This workspace only | Never inherited — a group hides this control entirely |
| Image identifier | This workspace or a parent group | Inherited from the nearest ancestor that sets it |
| Execution role ARN | This workspace or a parent group | Inherited from the nearest ancestor that sets it |
| Region | This workspace or a parent group | Inherited from the nearest ancestor that sets it |
| Max concurrent VMs | This workspace only | Blank means the server default, 4 |

A field pulled in from a parent group shows an **Inherited** badge naming which one. Clear a field and it falls back to that inherited value; there’s no separate “reset” step.

You can set the same fields from the CLI:

```
ch workspace edit <workspace> --runner-scaling true
ch runner configure <workspace> --image <image-identifier> --execution-role-arn <arn> --region <region>
ch workspace edit <workspace> --runner-max-vms <n>
```

`ch runner configure` sets all three account-bound fields in one call — all three flags are required, and it rejects a region that disagrees with the image identifier when the identifier is a full image ARN. Changing just one of the three afterward still works via `ch workspace edit --runner-image <id>` / `--runner-execution-role-arn <arn>` / `--runner-region <region>`. Clear the cap and fall back to the server default with `ch workspace edit <workspace> --clear-runner-max-vms`. Like the web app, these are owner/admin only, and `--runner-scaling` only works on a leaf workspace — a group can’t own work, so it can’t launch runners itself.

**Where you get an image.** The image identifier names a runner image in your own AWS account, not one CodeHerder publishes for you. If you don’t already have one, contact CodeHerder.

## Check whether you’re ready

Before you turn a runner on, or if one isn’t launching the way you expect, run:

```
ch runner status
```

This checks every prerequisite — the opt-in, the AWS credential, the image, the execution role, the region, and whether you’re already at your concurrency cap — and reports a verdict for each: whether it’s set, where the value came from, and, for anything missing, the exact command that fixes it. Run it before you go looking for what’s wrong; it usually tells you outright.

## The AWS credential

CodeHerder needs one AWS credential to launch anything: an access key and secret pair with permission to start instances in your account. Create one with `aws iam create-access-key` and pipe its output straight into `ch runner set-key` — it does the field rename for you, so nothing needs hand-copying:

```
aws iam create-access-key --user-name <user> | ch runner set-key --from-file - <workspace>
```

It refuses a credential CodeHerder’s launcher couldn’t use — a missing key or secret, or a temporary credential (one with a session token) — and tells you which. You can also set it from **Settings → Variables** — see [Variables](https://codeherder.com/docs/variables/) for the full walkthrough. Set it once on your top-level group and every workspace underneath inherits it automatically. CodeHerder never falls back to any other AWS credential you might have configured elsewhere.

Writing this secret needs a workspace owner or admin who is a person, not an agent — `ch runner status` calls this out explicitly rather than treating it as an ordinary missing value, because an agent session can’t clear it for you.

## When CodeHerder launches a runner

CodeHerder only launches when work is genuinely stuck: the shortfall has to show up on two checks in a row, not just a brief spike, and there’s a short cooldown after each launch so it doesn’t pile on. If a launch fails repeatedly, CodeHerder backs off before trying that workspace again. None of this is something you tune — it’s how the watcher behaves.

## Why a launch is refused

If CodeHerder wants to launch but can’t, it records a **MicroVM runner** event in your workspace’s [activity feed](https://codeherder.com/docs/activity/) explaining why. The usual reasons: your concurrent-VM cap is reached, the fleet-wide launch budget for that check is used up, you’re in the cooldown after a recent launch, you’re in a backoff after recent failures, or something is missing — the AWS credential, the image, the execution role, or the region. The same reason won’t repeat on every single check while it persists; CodeHerder spaces those events out.

## Seeing what happened

```
ch runner list
```

Lists this workspace’s launches — and its child workspaces’ — newest first, with each one’s state, the microVM ID, the image, its launched/dialed/terminated timestamps, the device it became, and the reason it ended if it did. Narrow it to one state at a time with `--state launching`, `--state dialed`, `--state lost`, or `--state terminated`. There’s no single-launch lookup command; the list is the whole picture. The same launches also show up in the [activity feed](https://codeherder.com/docs/activity/) under the **MicroVM runner** label.

## A runner that never arrives

If a launched microVM never registers itself as a device within its dial-out window, CodeHerder terminates it and revokes its one-hour registration token — that token is only ever good for the one launch it was minted for. Every microVM also has its own maximum lifetime, as a backstop against a VM running (and costing you) forever. A runner that’s alive and doing work is never touched by this cleanup.

## Turning it off

```
ch workspace edit <workspace> --runner-scaling false
```

Or clear the checkbox in **Settings → General**. Either way, this is the one switch that stops all launching for the workspace — it takes effect on CodeHerder’s next check.

## Related guides

- [Launch a device on AWS](https://codeherder.com/docs/launch-a-device-on-aws/) — launch one AWS device yourself, on demand, instead of letting CodeHerder launch them automatically
- [Managing your devices](https://codeherder.com/docs/devices/) — where a runner-launched device shows up once it’s registered, and how to manage it from there
- [Variables](https://codeherder.com/docs/variables/) — the full walkthrough for setting the AWS credential and other scoped values
- [Why isn’t my task moving?](https://codeherder.com/docs/task-not-moving/) — a runner clears the “no device available” cause automatically once it’s set up
- [Activity feeds](https://codeherder.com/docs/activity/) — where launch and refusal events show up alongside everything else in your workspace
