> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sfcompute.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Instances

> GPU compute instances — create, connect, and manage

<Warning>
  This feature is in [public preview](/preview/roadmap).
</Warning>

An instance is a GPU machine that runs a VM image. You create an instance, attach it to a
[pool](/preview/pools), choose an image, and optionally provide a cloud-init script. The
instance waits for compute time (from [orders](/preview/orders)) before starting.

## Instance lifecycle

| Status               | Description                                          |
| -------------------- | ---------------------------------------------------- |
| awaiting\_allocation | No allocation available on the pool right now        |
| running              | VM is up and accessible                              |
| terminated           | Allocation ended or instance was manually terminated |
| failed               | Something went wrong                                 |

An instance in `awaiting_allocation` starts running when the pool's allocation schedule covers
the current time. For example, if you buy compute starting at `now`, the instance starts within
about a minute. If the order starts in the future, the instance waits until then. The image
download and boot process takes up to 10 minutes before SSH is available.

## Create an instance

```bash theme={null}
sf instances create --pool dev --image ubuntu-22.04.5-cuda-12.7 --cloud-init ./startup.sh
```

All flags are optional in interactive mode — omit them to use pickers for pool and image.

```bash theme={null}
sf instances create
```

## Images

List available images to find one to use with your instance.

```bash theme={null}
sf images list
```

```
│ NAME        ubuntu-22.04.5-cuda-12.7
│ ID          image_TQiHEBzCA18ToAQqBtOr_
│ VISIBILITY  public
│ STATUS      completed
│ SIZE        8 GB
└ CREATED     Feb 23, 6:50pm UTC
```

Pass the image ID when creating an instance.

```bash theme={null}
sf instances create --pool dev --image ubuntu-22.04.5-cuda-12.7
```

To build and upload your own custom image, see [Custom Images](/preview/images).

## Cloud-init

Pass a startup script or cloud-config YAML via `--cloud-init` to configure the VM on first boot.

**Shell script** — inject your SSH public key:

```bash theme={null}
cat >startup.sh <<SCRIPT
#!/bin/bash

mkdir -p /root/.ssh
cat >>/root/.ssh/authorized_keys <<"EOF"
$(cat ~/.ssh/id_rsa.pub 2>/dev/null)
$(cat ~/.ssh/id_ecdsa.pub 2>/dev/null)
$(cat ~/.ssh/id_ecdsa_sk.pub 2>/dev/null)
$(cat ~/.ssh/id_ed25519.pub 2>/dev/null)
$(cat ~/.ssh/id_ed25519_sk.pub 2>/dev/null)
$(cat ~/.ssh/id_xmss.pub 2>/dev/null)
$(cat ~/.ssh/id_dsa.pub 2>/dev/null)
EOF
SCRIPT
```

**Cloud-config YAML** — set up users and keys declaratively:

```yaml startup.yaml theme={null}
#cloud-config
disable_root: false
ssh_pwauth: false
users:
  - name: root
    ssh_authorized_keys:
      - ssh-ed25519 AAAA... you@example.com
```

```bash theme={null}
sf instances create --pool dev --cloud-init ./startup.yaml
```

## Check instance status

```bash theme={null}
sf instances list
```

```
NAME        STATUS   POOL      INSTANCE SKU  CREATED
gpu-worker  running  dev       sea-3-h100    Mar 19, 4:40pm
```

Filter by time range.

```bash theme={null}
# Instances from the last 24 hours
sf instances list --created-after 24h

# Instances within a specific window
sf instances list --created-after 2025-03-01 --created-before 2025-03-08

# Instances from a specific calendar month
sf instances list --month 2025-05
```

`--created-after` and `--created-before` accept a datetime, Unix timestamp, or a duration like `24h` or `7d` (meaning 24 hours or 7 days ago, respectively). You can also use `--since` and `--until` as aliases.

Get details on a specific instance.

```bash theme={null}
sf instances get gpu-worker
```

## SSH into an instance

```bash theme={null}
sf instances ssh {instance-name}
```

<Note>
  The instance must be in `running` status and the image must be fully booted. This can take up to 10
  minutes after the instance starts.
</Note>

## View logs

```bash theme={null}
sf instances logs {instance-name}
```

Show more lines.

```bash theme={null}
sf instances logs {instance-name} --limit 500
```

Filter by time range.

```bash theme={null}
# Lines from the last hour
sf instances logs {instance-name} --after "in -1h"

# Lines within a window
sf instances logs {instance-name} --after 2025-05-22 --before "now"
```

`--after` and `--before` accept flexible time expressions: `"now"`, `"in -1h"`, a date like `mar 1`,
ISO 8601, or a Unix timestamp.

## Terminate an instance

Stop the VM immediately. The instance moves to `terminated` status.

```bash theme={null}
sf instances terminate {instance-name}
```

## Replace an instance

Replace an instance with a new one on the same pool. The original instance is terminated and a
new instance is created with the specified image.

```bash theme={null}
sf instances replace {instance-name} --image ubuntu-22.04
```

Provide a cloud-init script for the replacement:

```bash theme={null}
sf instances replace {instance-name} --image ubuntu-22.04 --cloud-init ./startup.yaml
```

Give the replacement instance a specific name:

```bash theme={null}
sf instances replace {instance-name} --image ubuntu-22.04 --name worker-2
```

<Note>
  Cloud-init is not carried over from the original instance. If you omit `--cloud-init`, the
  replacement boots with no startup script and you won't be able to SSH into it.
</Note>

## Delete an instance

Permanently remove an instance.

```bash theme={null}
sf instances delete {instance-name}
```

## Replace an instance

Replace an instance with a new one on the same pool and SKU. The original instance is terminated and a fresh instance is created with a new image (and optionally a new startup script and name).

```bash theme={null}
sf instances replace {instance-name} --image ubuntu-22.04.5-cuda-12.7
```

The replacement inherits the original's pool, SKU, subnet, public IPv4 setting, firewall, tags, and priority.

Replace with a new startup script

```bash theme={null}
sf instances replace {instance-name} --image ubuntu-22.04.5-cuda-12.7 --cloud-init ./new-startup.sh
```

<Note>
  If you omit `--cloud-init`, the replacement starts with no startup script — you will not be able to SSH into it. Pass a cloud-init file to configure SSH access.
</Note>

Replace with a specific name

```bash theme={null}
sf instances replace {instance-name} --image ubuntu-22.04.5-cuda-12.7 --name worker-2
```

<Warning>
  There is no persistent storage attached to an instance. Replacing an instance will result in loss of all data stored on the original.
</Warning>

## Instance priority

When a pool's quota drops below the number of running instances, the system terminates instances
to match. Instance priority controls which ones survive. Higher-priority instances are kept longer;
lower-priority ones are terminated first.

Priority has four arms, ordered `yield < normal < preferred < critical`. Every instance defaults to
`normal`. The `expected_shutdown_at` field on instance responses is deprecated and always `null`.

| Arm         | Meaning                                              |
| ----------- | ---------------------------------------------------- |
| `yield`     | Surrender this instance first when the pool shrinks. |
| `normal`    | Default. No special preference.                      |
| `preferred` | Keep this instance over `normal` ones when possible. |
| `critical`  | Keep this instance over everything else.             |

Set priority on an existing instance.

```bash theme={null}
sf instances set gpu-worker --priority critical
```

Set priority at create time.

```bash theme={null}
sf instances create --pool dev --image ubuntu-22.04.5-cuda-12.7 --priority critical
```

The same surface is available over the API. Pass `priority_level` in the body of
`POST /preview/v2/instances` to set it at create time.

```json theme={null}
POST /preview/v2/instances
{
  "pool": "pool_xxx",
  "image": "img_xxx",
  "priority_level": "critical"
}
```

Omit `priority_level` to default to `normal`.

Update one instance with `PATCH /preview/v2/instances/{id}`.

```json theme={null}
PATCH /preview/v2/instances/inst_xxx
{ "priority_level": "preferred" }
```

Omit `priority_level` to leave it unchanged. Pass `"normal"` to reset to the default.

Update many instances atomically by PATCHing the collection.

```json theme={null}
PATCH /preview/v2/instances
{
  "data": [
    { "id": "inst_aaa", "priority_level": "critical" },
    { "id": "inst_bbb", "priority_level": "yield" },
    { "id": "inst_ccc", "priority_level": "normal" }
  ]
}
```

If any entry is rejected (unknown id, cross-account id, missing permissions), the entire request
rolls back with a `422` and no instance is touched. Up to 10,000 entries per call. An empty `data`
returns `200` with no writes. When the same `id` appears more than once, the last occurrence wins.

The response includes the updated instance for each entry, so you can confirm the result in one
round-trip.

When two instances have the same priority, the newer one is terminated first.

### `critical` and procurement automations

`critical` cannot be set on an instance whose pool has an active procurement automation —
procurement-backed pools resize automatically, so `critical` can't be honored there. The
constraint applies in both directions:

* Setting `priority_level: critical` on such an instance returns `422`.
* Creating a procurement on a pool that already has `critical` instances returns `422` —
  downgrade the affected instances (for example, to `preferred`) first.

Use `preferred` instead when the pool is procurement-backed, or disable the procurement before
setting `critical`.

Setting priority requires the `Node: Write` permission. Read-only tokens see `priority_level` on GET
responses but receive `403` on writes.

## Limitations

* No persistent storage. If the underlying machine dies, you get a replacement but not the same
  disk.
* No public IPs. To serve inference, set up a proxy in another cloud and connect it via VPN.
* No InfiniBand.
* Instances don't share a VPC or VLAN. Configure a VPN if you need connectivity between instances.
* Boot time can be up to 10 minutes for image download and startup.
* No GPU monitoring. GPUs may occasionally fall off the bus — terminate and recreate the instance,
  or contact us.

### API reference

See the [Instances API](/preview/api-reference/instances/list-instances) for programmatic access.
