---
title: "VMs"
description: "Create virtual machines on your own servers or the Frazer fleet from a plan, with machine types, images, local or replicated disks, SSH sign-in and instance groups."
url: https://frazer.ai/docs/vms
index: https://frazer.ai/docs/llms.txt
tokens: 6175
---

> For agents: this page is indexed at https://frazer.ai/docs/llms.txt, and every page at https://frazer.ai/llms.txt. Copy commands from this file exactly.

# VMs

VMs are virtual machines you create from a plan, on a pool of your own servers or on the Frazer fleet. You pick a machine type, an image and disks, and the plan shows the price and the servers the VM fits on before anything runs. Each VM sits in your project’s network and signs people in with their Frazer account, so there are no SSH keys to hand out. On your own servers a VM has no per-VM charge.

Product overview: [VMs](https://frazer.ai/vms).

## How it works

A Frazer VM is a hardware virtual machine. It runs on Frazer’s VM layer in your project’s own namespace, either on the servers of a pool your project owns or one shared with it, or on the Frazer fleet. You see a VM, never Kubernetes: you create and change it through the Frazer API from the console, the CLI or MCP, and nobody runs `kubectl` against the servers underneath. On shared servers every workload is its own VM, and the servers never run your containers directly.

Every create and change is a plan you apply. The plan checks your project’s quota and the free capacity on real servers (“fits on 2 of 3 servers”), shows the cost, and then applies as an operation. Each applied change becomes a revision of the VM.

-   **Machine type**: the VM’s size, from a series or a custom shape. `g1-4` is 4 vCPU and 16 GiB.
-   **Placement**: where the VM runs. `--pool` names a server pool of your project or one shared with it; `--location` names a Frazer fleet region. The rest of the spec is the same.
-   **Image family**: a name such as `ubuntu-2404-lts` that points to the newest usable image of an operating system.
-   **Disk**: `local-nvme` (fast, stays on one server), `replicated` (survives a server and moves with the VM) or `scratch` (erased on stop). The disk type decides whether a VM can move.
-   **Snapshot** and **backup**: a snapshot copies one disk next to it; a backup copies the whole VM, every disk and its settings, to Frazer Storage.
-   **Instance template** and **instance group**: an immutable VM spec, and a group of identical VMs made from it that heals, scales and updates together.
-   **SSH sign-in**: a certificate that lasts minutes and opens one VM, issued after an access check.
-   **Guest agent**: Frazer’s agent inside the VM. It serves the VM’s metadata, runs startup scripts and trusts the SSH sign-in certificate authority. Images also boot with cloud-init alone.

### Machine types

| Series | For | vCPU : memory | CPU |
| --- | --- | --- | --- |
| `s1` shared | Development, small services, CI runners | 1 : 2–4 GiB | Shared up to 2:1, stated on the price |
| `g1` general | Most workloads; the default | 1 : 4 GiB | 1:1 |
| `c1` compute | CPU-bound work | 1 : 2 GiB | Dedicated (pinned) cores |
| `m1` memory | Caches, in-memory analytics | 1 : 8 GiB | 1:1, with a hugepages option |
| `x1` exclusive | Latency-critical work, per-core licenses | As `c1` or `g1` | Dedicated cores and the NUMA topology passed through, on servers that report it |
| `gpu-<model>-<n>` | GPU work | Fixed per GPU | Dedicated; whole GPUs by direct PCI passthrough |
| `custom-<vcpu>-<mib>` | Right-sizing | 1 : 1–8 GiB in 256 MiB steps | As the series, at the same unit price |

Sizes are 1, 2, 4, 8, 16, 32, 48, 64 and 96 vCPU. On your own servers, the largest size is the biggest server in the site minus the reserve each server keeps for itself (8 cores and 32 GiB). Memory is never overcommitted, and the VM’s own overhead counts against the server.

### Network

Each VM has one to eight network interfaces, each in a subnet of a VPC network in your project. An interface has an internal address, ephemeral or reserved (an IPv4 address and an IPv6 address on a dual-stack subnet), and two separate external choices, `external_ipv4` and `external_ipv6`. Each is none, ephemeral or static, and **both default to none**. Tags on the interface select firewall rules, and `ip_forwarding` turns a VM into an appliance.

-   The internal address survives a restart and a live migration.
-   Port security is on: a VM cannot spoof another address.
-   By default nothing reaches the VM from the internet. Traffic from Frazer Link and from the network’s own subnets is allowed. Outbound traffic leaves through the network’s NAT, or through the VM’s own external address.
-   Outbound port 25 is blocked on both address families.
-   Each VM gets a private name, `{vm}.{subnet}.{network}.{project}.internal`.

Firewall rules, NAT and load balancers are covered in [VPC and firewall](https://frazer.ai/docs/network).

### Host maintenance

Each VM has two settings: what happens on host maintenance (`MIGRATE` or `TERMINATE`) and whether it restarts automatically. A VM whose disks are all `replicated` and that has no passed-through device defaults to `MIGRATE`: it moves to another server and the guest does not notice. Every other VM defaults to `TERMINATE`: it stops and starts again inside your project’s maintenance window.

Frazer gives notice through the VM’s metadata (`maintenance-event`), a console banner, webhooks and email: 7 days ahead of planned work on a `TERMINATE` VM, 60 seconds before a live-migration blackout, and 60 minutes ahead for GPU VMs, which can never migrate. To take a planned restart early, call the VM’s `performMaintenance` method. When a server in a shared pool needs work, every project with VMs on it sees the event in its own maintenance calendar.

## Create a VM

You need a project, and either a server pool in it or shared with it, or access to a Frazer fleet region. See [Servers and pools](https://frazer.ai/docs/servers) for pools.

1.  Plan the VM. Nothing is created yet.
    
    ### CLI
    
    ```sh
    frazer compute vms create web-1 --project acme-staging \
        --pool vint-hill-default --machine-type g1-4 \
        --image-family ubuntu-2404-lts --boot-disk 50,local-nvme \
        --subnet default \
        --external-ipv4 ephemeral --external-ipv6 ephemeral \
        --dry-run
    ```
    
    ```text title="Output"
    Plan      + VM web-1 · g1-4 · 4 vCPU · 16 GiB
              + Disk web-1-boot · 50 GiB local-nvme · daily backups
              + NIC nic0 in default · external IPv4 and IPv6
    Fits on   3 of 3 servers in Vint Hill
    Compute   no charge · covered by acme-infra
    ```
    
    To place the same VM on the Frazer fleet, replace `--pool vint-hill-default` with `--location us-virginia1`.
    
    ### Console
    
    Open **Compute › VM instances › Create VM**. One page holds every choice:
    
    -   **Name** and where the VM runs: your project’s pools, then pools shared with the project, then the Frazer fleet, cheapest first, each with the capacity it has free.
    -   **Machine type**, with its price and the servers it fits on.
    -   **Image family**, **boot disk** type and size, data disks.
    -   **Network** and subnet, external addresses, sign-in (SSH sign-in is on), startup script, and backups (on for `local-nvme`).
    -   **Advanced**: placement group, maintenance policy, labels and service account.
    
    The right rail shows the cost, the quota impact and the plan diff. **Copy as CLI / API / YAML** gives you the same VM as code.
    
2.  Apply the plan.
    
    ### CLI
    
    Run the same command without `--dry-run`. The CLI waits for the operation to finish; add `--async` to return at once.
    
    ### Console
    
    Choose **Apply**.
    
    In a production project, someone other than you approves the plan before it applies. Agents and service accounts never approve.
    
3.  Sign in.
    
    ```sh
    frazer compute vms ssh web-1 --tunnel
    ```
    
    The CLI gets a certificate for `web-1` and connects through Frazer Link, so a VM without an external address needs no bastion host.
    

> **A local-nvme boot disk stays on one server:** Fast. Stays on one server. If that server fails, this VM comes back from its last backup (daily by default). Backups are on by default for VMs with `local-nvme` disks. Use `replicated` disks for a VM that must survive the loss of a server.

Every VM is also a declarative resource: `frazer export` writes it as YAML in the same schema as the [Terraform and OpenTofu provider](https://frazer.ai/docs/terraform), and `frazer apply -f` applies such a file with a plan first.

## Connect to a VM

### SSH sign-in

`frazer compute vms ssh web-1` asks Frazer for an SSH user certificate that lasts 5 to 10 minutes. It is issued from your organization’s SSH certificate authority, the same one devboxes use, only after an access check on that VM, and it carries a principal bound to that VM, so it opens no other. The VM trusts the authority through cloud-init.

-   `compute.vms.login` lets you sign in; `compute.vms.adminLogin` adds sudo. Grant them on a project, a group or one VM.
-   Without `--tunnel`, the CLI connects to the VM’s external address. With `--tunnel`, it forwards TCP through Frazer Link.
-   Remove the role and access ends: certificates expire within minutes, and there are no keys on the VM to clean up.
-   Your organization can require a passkey or TOTP step for sudo sessions.

Images without the guest agent can use SSH public keys from project or VM metadata instead. When your organization requires SSH sign-in, those keys are ignored. Nobody ever reads a stored VM password: on Windows, **Reset password** generates one, shows it once to the person who asked, and stores nothing.

### Use the console and rescue mode

```sh
frazer compute vms console web-1
frazer compute vms console web-1 --vnc
```

The serial console and VNC also open in the browser on the VM’s **Console** tab, through Frazer Link. They need `compute.vms.console`, and your organization can turn the serial console off. For a VM that does not boot:

-   The **Logs** tab keeps the serial log, so you can read it after a crash.
-   The VM page shows a VNC screenshot.
-   Rescue mode restarts the VM into a Frazer rescue image with its disks attached.

### Metadata and startup scripts

On first boot, cloud-init (Linux) or Sysprep (Windows) applies the user data from the VM’s spec. Inside the VM, the guest agent serves the metadata document at `169.254.169.254`: project and VM metadata, labels, the sign-in policy, maintenance events and a token endpoint. It reaches Frazer over vsock, not the network, so a forged request from an application cannot read another VM’s metadata.

-   Set `startup-script` or `startup-script-url` in metadata to run a script at boot; the agent also runs shutdown scripts.
-   Attach a service account and the token endpoint returns a short-lived Frazer token, so the VM never holds a static key.

## Work with images

Frazer’s public images are built from the upstream cloud images with cloud-init defaults and the guest agent, signed, and cached on every site, so a first boot never downloads over the WAN. Families: Ubuntu 24.04 and 26.04 LTS, Debian 13, Rocky and Alma 10, Fedora and Flatcar. Windows Server runs with your own license.

Make your own image from a disk or a snapshot, or bring one:

```sh
frazer compute images create --upload ./disk.qcow2 --family app-base
frazer compute images create --from-disk web-1-boot --family app-base
```

-   Imports accept qcow2, raw, VMDK, VHD, VHDX and ISO: from a URL with `--from-url`, as an upload from the CLI or from **Compute › VM instances › Images** in the browser, or from an OCI registry. Imports have a size limit per organization.
-   To capture a VM, choose **Create image** on the stopped VM, or on a running VM while the guest agent freezes the file system.
-   Images belong to a project and can be shared with other projects of your organization.
-   You can export any image or disk at any time.

A family points to its newest image that is not deprecated. To roll a family back, deprecate its newest image.

| State | New VMs |
| --- | --- |
| `READY` | Allowed |
| `DEPRECATED` | Allowed, with a warning |
| `OBSOLETE` | Refused |
| `DELETED` | Refused; the image is gone |

## Manage disks, snapshots and backups

| Property | `local-nvme` | `replicated` | `scratch` |
| --- | --- | --- | --- |
| Backing | A volume on the server’s NVMe, encrypted with LUKS2 | Block storage replicated across servers in the site | The server’s NVMe, erased on stop |
| Speed | Native NVMe | Network block: fewer IOPS, more latency | Native NVMe |
| If the server dies | Back from its last backup; writes since then are lost | Restarts on another server in the site, no data lost | Lost |
| Live migration | No: stop, maintain, start | Yes | No |
| Snapshots | Restore on the same server | Restore anywhere in the site | None |
| Resize | Grow online; shrink by copying to a new disk | Grow online; shrink by copying to a new disk | Fixed |
| Good for | Databases on VMs, build boxes, stateless VMs in a group | Long-lived VMs, Windows, anything that must survive a host | Caches, temporary files |

-   Attach and detach data disks on the VM’s **Disks** tab, or with `frazer storage disks attach` and `detach`, also while the VM runs.
-   A small `local-nvme` disk can be moved to another server while it runs, and a `local-nvme` disk can change to `replicated` online.
-   On your own servers, `replicated` disks need a site with at least three servers in the pool and 25 GbE networking.
-   Every disk is encrypted with LUKS2 and erased cryptographically on delete. On a shared pool, each `local-nvme` VM disk has its own key, kept in your project’s secrets namespace, so the project that hosts the pool cannot read it.

| Property | Snapshot | Backup |
| --- | --- | --- |
| Scope | One disk | The whole VM: every disk and its settings |
| Where | Next to the disk; lost with a `local-nvme` server | Frazer Storage, incremental, with an optional off-site copy |
| Consistency | Crash, or app-consistent with a guest-agent freeze | The same |
| Restore | A new disk, or over the disk of a stopped VM | Always a new VM, or over the disks of a stopped VM after you type to confirm |

Back up VMs by label on a schedule:

```sh
frazer compute backup-policies create daily --schedule "0 3 * * *" --keep 14 \
    --vms label:environment=production
```

Snapshots and backups are named objects you delete yourself. No deploy, migration or maintenance ever deletes one.

## Run groups of VMs

An instance group keeps identical VMs healthy, scaled and updated together. It is made from an instance template, an immutable, versioned spec with the machine type, the image family or a pinned image, disks, metadata, network interfaces and sign-in settings.

```sh
frazer compute instance-templates create web-v3 --from-vm web-1
frazer compute instance-groups create web --template web-v3 --size 3 \
    --autoscale cpu=60,min=2,max=10
```

-   **Placement**: a pool or a region, spread across servers. A group is stateless, or stateful when it must keep each VM’s disks and name.
-   **Autohealing**: an HTTP, TCP or gRPC health check runs next to each VM; after a set number of failures the group recreates the VM, after an initial delay you choose.
-   **Autoscaling**: on CPU, on a custom PromQL metric from your project’s metrics, or on a schedule, with a minimum, a maximum, a cool-down and scale-in protection.
-   **Updates**: point the group at a new template with **Edit group** under **Compute › VM instances › Instance groups**. A rolling update replaces VMs within `maxSurge` and `maxUnavailable`; a canary runs a second template on a share of the group. **Pause** stops an update, and rolling back is a plan like any change.
-   **Load balancing**: a group is a backend of a load balancer in your VPC. See [Load balancers](https://frazer.ai/docs/load-balancers).

Placement groups apply to single VMs too: `spread` puts VMs on different servers, `compact` keeps them in the same rack.

## Stop, resize and delete

```sh
frazer compute vms stop web-1
frazer compute vms start web-1
```

A stopped VM keeps its disks and pays only for storage. To change the machine type, stop the VM, run `frazer compute vms resize`, and start it again; this always works. A VM whose disks are all `replicated` can change vCPU and memory without a restart.

To move a VM to another site, back it up and restore the backup at the other site.

`frazer compute vms delete web-1` offers a final backup first. Deletion is soft: within the restore window, `frazer compute vms undelete web-1` brings the VM back. Disks are soft-deleted the same way.

## Access and audit

| Who | What they can do |
| --- | --- |
| Admins and developers | Create and change VMs, sign in (`compute.vms.login`) and use sudo (`compute.vms.adminLogin`) |
| Viewers and responders | See VMs, disks and their state; they cannot sign in |
| Agents | Plan any change under their ceiling. Console sessions, sudo sign-in and a reset of a production VM need a person to approve |
| Your organization’s policies | Allowed machine types, sites and regions, external addresses, the serial console, and the number of VMs |

-   Your organization can require explicit sign-in bindings in production projects; this policy is on by default.
-   Every VM method is also an MCP tool. Read tools answer at once; a write returns a plan that waits for approval.
-   In a production project, a second person approves each plan. Nobody approves their own plan.
-   Placing a VM on a pool shared with your project needs no extra permission by default.

What is logged:

-   Every change, applied from a plan and kept in the VM’s revision history.
-   Every sign-in: who, which VM, which principal, and on whose behalf for agents.
-   Console sessions: start, end and person. Keystrokes are not recorded by default.
-   Maintenance notices, in the VM’s metadata, the console, webhooks and email.
-   On a shared pool, the project that hosts the pool sees each placement on its servers (resource name and size) and nothing inside your VMs.

## Limits and quotas

| Limit | Value |
| --- | --- |
| Network interfaces per VM | 1 to 8 |
| Machine sizes | 1, 2, 4, 8, 16, 32, 48, 64 and 96 vCPU; on your servers, up to the biggest server minus 8 cores and 32 GiB |
| Custom shapes | 1 to 8 GiB per vCPU, in 256 MiB steps |
| Memory overcommit | None |
| CPU sharing | `s1` up to 2:1; every other series 1:1 or dedicated |
| SSH sign-in certificate | 5 to 10 minutes |
| External addresses | None by default |
| Outbound port 25 | Blocked by default |
| Image imports | A size limit per organization |
| Labels | Up to 64 per resource; keys and values up to 63 characters |
| Maintenance notice | 7 days before a planned restart; 60 seconds before a migration blackout; 60 minutes for GPU VMs |

Every plan checks your project’s quotas and, on a shared pool, your share of it: the capacity guaranteed to your project and the limit it may burst to. Quotas and quota increases are covered in [Servers and pools](https://frazer.ai/docs/servers).

## Pricing

On your own servers the server fee covers a VM’s compute; on the Frazer fleet you pay per second while it runs. A stopped VM pays only for storage: disks, snapshots, backups and images per GiB-month, and a reserved external IPv4 address per IP-hour at cost (IPv6 is free).

| VMs | On your servers | On the Frazer fleet |
| --- | --- | --- |
| Price | **Included** | Same rates · a 4 vCPU / 16 GiB box ≈ $0.232 / hour |

Every line, with the estimator: [pricing](https://frazer.ai/pricing#lines).

## Troubleshooting

| Symptom | Cause | Fix |
| --- | --- | --- |
| The plan fails with `QUOTA_EXCEEDED` | The VM would take the project past a quota | Pick a smaller machine type, delete what you no longer use, or follow the error’s link to request more |
| The plan fails with `POOL_NO_FIT` | No single server in the pool has room for this shape | Pick a smaller machine type or another pool, or add a server |
| The plan fails with `POOL_CAPACITY_EXHAUSTED` | Your project is at its limit on the shared pool, or the pool is full | Use the plan’s **request more guaranteed** option, or place the VM on the Frazer fleet |
| The plan fails with `POOL_NOT_SHARED` or `POOL_SHARE_DRAINING` | The pool is not shared with your project, or the share is ending | Choose another pool; ask the pool’s admins about the share |
| New VMs are refused for an image | The image is `OBSOLETE` | Use the family, or a newer image |
| `frazer compute vms ssh` is denied | You lack `compute.vms.login`, or the project requires explicit sign-in bindings | Ask an admin for the role on the project or the VM |
| SSH times out | The VM has no external address, or no rule allows your traffic | Add `--tunnel` to go through Frazer Link |
| Metadata SSH keys are ignored | Your organization requires SSH sign-in | Sign in with `frazer compute vms ssh` |
| The VM does not boot | A broken image, disk or startup script | Read the serial log on the **Logs** tab, check the VNC screenshot, or restart into rescue mode |
| Mail from the VM does not leave | Outbound port 25 is blocked by default | Send through a mail service on another port |
| The VM stopped after its server failed | Its disks are `local-nvme` | Restore the last backup to a new VM; use `replicated` disks for VMs that must survive a server |
| The machine type cannot change while running | Changing vCPU and memory live needs all disks `replicated` | Stop the VM, resize it, start it |
| A VM on the Frazer fleet stopped | A budget cap was reached; its disks are kept | A billing admin lifts the cap, then start the VM. VMs on your own servers are never stopped by a cap |
| VMs on a shared pool stopped | The pool was unshared and its grace period ended; disks stay 30 days | Snapshot to Frazer Storage, or move the VM to another pool or the fleet |

To see why traffic is blocked, list the rules that apply to a VM, or test a path:

```sh
frazer network firewall-policies get-effective --vm web-1
frazer network connectivity-tests run --from vms/web-1 --to databases/orders --port 5432
```

## Reference

### CLI

| Command | What it does |
| --- | --- |
| `frazer compute vms create` | Create a VM from a plan, on a server pool or in a Frazer fleet region. |
| `frazer compute vms list` | List the VMs in a project. |
| `frazer compute vms get` | Show one VM with its state, machine type, placement, disks and addresses. |
| `frazer compute vms ssh` | Sign in over SSH with a short-lived certificate; --tunnel goes through Frazer Link. |
| `frazer compute vms console` | Open the VM's serial console; --vnc opens the graphical console. |
| `frazer compute vms stop` | Stop a VM. Its disks stay, and it pays for storage only. |
| `frazer compute vms start` | Start a stopped VM. |
| `frazer compute vms reset` | Hard-reset a VM. |
| `frazer compute vms resize` | Change a VM's machine type. |
| `frazer compute vms migrate` | Live-migrate a VM whose disks are all replicated to another server in the site. |
| `frazer compute vms delete` | Delete a VM. Deletion is soft, with a restore window, and offers a final backup first. |
| `frazer compute vms undelete` | Restore a deleted VM inside its restore window. |
| `frazer storage disks create` | Create a local-nvme, replicated or scratch disk, blank or from an image or a snapshot. |
| `frazer storage disks attach` | Attach a disk to a VM, also while it runs. |
| `frazer storage disks detach` | Detach a disk from a VM. |
| `frazer storage disks resize` | Grow a disk while it is in use. |
| `frazer compute snapshots create` | Snapshot one disk, crash-consistent or app-consistent. |
| `frazer compute snapshots restore` | Restore a snapshot to a new disk, or over the disk of a stopped VM. |
| `frazer compute images create` | Create an image in a family from a disk, a URL or an uploaded file. |
| `frazer compute instance-templates create` | Create an immutable, versioned VM spec, for example from an existing VM. |
| `frazer compute instance-groups create` | Create a group of identical VMs from a template, with autohealing and autoscaling. |
| `frazer compute backup-policies create` | Back up the VMs that match a label on a schedule and keep a number of backups. |

All of them: [CLI reference](https://frazer.ai/docs/cli).

## Related

-   [VMs product page](https://frazer.ai/vms)
-   [Servers and pools](https://frazer.ai/docs/servers)
-   [Volumes and snapshots](https://frazer.ai/docs/volumes)
-   [VPC and firewall](https://frazer.ai/docs/network)
-   [Kubernetes](https://frazer.ai/docs/kubernetes)
-   [CLI reference](https://frazer.ai/docs/cli)

## Pages in Compute

- [Servers and pools](https://frazer.ai/docs/servers.md)
- [Kubernetes](https://frazer.ai/docs/kubernetes.md)
- [Serverless](https://frazer.ai/docs/serverless.md)
- [VMs](https://frazer.ai/docs/vms.md) (this page)
- [Devboxes](https://frazer.ai/docs/devboxes.md)
