Service guide / 01

Compute

Compute lets you run virtual machines — instances — on demand, without owning or managing the physical hardware yourself. You choose an image to boot from, attach storage and a network interface, and the platform places it on a host and keeps it running.

API GraphQL · compute CLI origin compute Status values 8

Key concepts

Instance
A virtual machine. Everything else on this page describes how to create, run, and manage one.

Image
A template an instance boots from — the operating system and whatever else was baked into it. You choose one when you launch an instance. Images are either your own (created from one of your volumes’ snapshots) or platform-provided base images (e.g. a Debian base image) that any project can launch from without first creating a copy.

Instance type
The hardware size and family you launch an instance with, e.g. gp1.core.2 — you choose one at launch, and it fixes the instance’s vCPU and memory for its entire life; there’s no in-place resize. The first segment (gp1, gp2, e1, …) is the kind — a hardware family with its own fixed memory-per-vCPU ratio, and instances of one kind only ever run on hosts built for that kind. The last segment is the vCPU count; memory is always a fixed multiple of it (never chosen independently). See the full, current list of launchable instance types via the GraphQL API’s instanceTypes query or the CLI’s list-instance-types command.

Key pair
An SSH key pair. You import the public half once; from then on, you reference it when launching an instance, and the platform injects it into the guest so you can log in with the matching private key.

Volume
An instance’s disk. Every instance has at least a root volume, created from its image. Volumes come in two backends with different guarantees — see Choosing a storage backend.

Security group
A set of rules controlling what network traffic can reach and leave an instance’s network interface. See Controlling access with security groups.

Instance lifecycle

An instance moves through a small set of states over its life. Knowing them is useful for building your own automation around instances — e.g. polling until one is ready, or deciding whether it’s safe to retry an action.

  1. You launch an instance. Along with an image, key pair, and network placement, you choose an instance type (see Key concepts) — this fixes the instance’s vCPU and memory for its entire life. It starts out getting its storage and network resources ready — it isn’t running or reachable yet. Once everything it needs is ready, it automatically requests to start.
  2. It starts running. Once the platform confirms it’s actually up, it’s reachable and serving traffic.
  3. You can stop it. This shuts the instance down without deleting it — its network interface stays reserved, so you can start it again later and get the same instance back. Stopping and restarting is only available for instances using pvs storage (see below) — an instance using host_local storage can only be terminated, not stopped. Once stopped, an instance no longer counts against your compute usage — its vCPU and memory are released; its pvs volume keeps existing and being billed while stopped.
  4. You can start it again. A stopped instance goes back through the same startup sequence and becomes running again — possibly on a different physical host than before, though that’s not something you need to plan around; your volumes and network interface stay attached and reachable the same way either way.
  5. You can terminate it. This is permanent — the instance, its network interface, and its volumes are all released for good; there’s currently no way to keep an instance’s volumes after terminating it. Terminating is safe to call more than once; if you’re not sure a previous attempt fully completed, just call it again rather than trying to infer completion from status alone. A terminated instance stays visible when you list instances for a while after termination, then drops out of the default list — you can still look it up directly by id at any time, no matter how long ago it terminated.

launch-instance

resources ready

host confirms up

stop-instance

start-instance

poweroff inside guest

terminate-instance

terminate-instance

start-instance

terminate-instance

INITIALIZING

PENDING

RUNNING

STOPPING

STOPPED

SHUTTING_DOWN

TERMINATED

FAILED

Any transitional state
lands here if the host
refuses. Never resolves
on its own.

Instance lifecycle. Blue states are transitional — they resolve on their own, so these are the ones to poll through. Green (running), grey (stopped, terminated) and red (failed) only ever change because you asked for something. Failure edges are summarised in the note rather than drawn four times.

Any of steps 1–5 can fail on the host it was asked of — see When a lifecycle operation fails.

Instance status values

An instance’s status is one of exactly these eight values, and nothing else. It’s a typed enum on the API, so if you’re generating a client from the schema you get the full set and a compile error when a new one appears — don’t compare against strings you’ve seen in a response.

statusWhat it means
INITIALIZINGJust created. Its storage and network resources are still being made ready — not running, not reachable. Moves on by itself.
PENDINGEverything it needs is ready and it has been asked to start — the initial start, or a restart from STOPPED/FAILED. Not running yet. Moves on by itself.
RUNNINGUp and reachable.
STOPPINGYou asked for a stop; it may still be live until it actually shuts down. Moves on by itself.
STOPPEDNot running, but still yours: the network interface stays reserved and you can start it again. Its vCPU and memory are released; a pvs volume keeps existing and being billed.
SHUTTING_DOWNYou asked to terminate a live instance and it’s being shut down first. Nothing is released yet. Moves on by itself.
TERMINATEDPermanently gone; resources released. Nothing leaves this state.
FAILEDThe host didn’t do what it was asked. See When a lifecycle operation fails — this is the only status that carries a statusReason.

The four transitional statuses (INITIALIZING, PENDING, STOPPING, SHUTTING_DOWN) resolve on their own, so they’re the ones to poll through. RUNNING, STOPPED and FAILED only ever change because you asked for something — with one exception worth knowing about if you poll: an instance you shut down from inside the guest (poweroff, or anything else that stops the operating system) goes to STOPPED on its own, without passing through STOPPING, because nothing asked the platform for a stop. Start it again the usual way.

Changed: SHUTTING_DOWN used to come back as SHUTTING DOWN, with a space. If you have automation matching that older spelling, update it — nothing else about the value set changed.

Is my instance actually working?

status and health answer two different questions, and you need both.

status tells you what was asked for — every one of its values is the result of a command you or the platform issued. Health tells you what the platform can currently observe. An instance whose host has become unreachable is still RUNNING: nothing stopped it, and the platform won’t pretend otherwise. So RUNNING on its own does not mean “confirmed working”.

healthChecks on an instance gives you both a per-check breakdown and an availability summary for when you just want one indicator per row.

Each check reports one of four things, and the third matters most:

  • OK — the check ran and your instance passed.
  • IMPAIRED — the check ran and your instance failed it.
  • INSUFFICIENT_DATA — the platform could not tell, usually because the host carrying your instance is unreachable. This is not a quieter way of saying OK. It means the platform has lost the thing that would have observed your instance, and you should treat it as “unknown”, not “fine”.
  • NOT_APPLICABLE — the check doesn’t apply right now. A stopped instance isn’t unhealthy; it just isn’t running.

availability aggregates them, and only ever reports AVAILABLE when every applicable check actually passed. If anything is unknown, the summary says UNKNOWN rather than rounding up.

Each check also carries a category, which is the part that tells you what to do:

  • SYSTEM — the platform underneath your instance. There is nothing to fix inside the instance; the operator is the one who has to act.
  • INSTANCE — your instance’s own operating system and network configuration. Waiting will not help.

That distinction is why the individual checks exist rather than a single indicator. If you only read availability, you lose the one piece of information that tells you whether it’s your problem.

Not every check is implemented yet. Today the platform reports on what the host running your instance observes about it, on whether its network interfaces have carried traffic recently, and on whether that host is reachable at all. The in-guest agent check reports NOT_APPLICABLE, because the images available today ship no agent for it to talk to — a check with nothing to observe says so rather than claiming it could not tell. A healthy instance therefore reads AVAILABLE: NOT_APPLICABLE does not hold the aggregate down, whereas INSUFFICIENT_DATA would.

When the host carrying your instance becomes unreachable, you will see the host reachability check go IMPAIRED with category SYSTEM, and the instance-level checks fall back to INSUFFICIENT_DATA shortly after. Read that combination as “the platform has lost sight of this instance” rather than “this instance has stopped” — the platform genuinely cannot tell which, and it will not claim otherwise. Your instance’s status stays whatever it was, because nothing commanded it to change.

Two consequences worth knowing while that is true:

  • A check that has not been refreshed goes back to INSUFFICIENT_DATA. Results are not kept indefinitely — if the host carrying your instance stops reporting, its checks age out within a couple of minutes rather than continuing to show their last value. The platform would rather tell you it has stopped looking than repeat something it can no longer confirm.
  • A quiet instance is never reported unhealthy for being quiet. Network activity can only ever confirm your instance is alive; its absence means nothing, because an idle instance sends nothing. When an instance has been quiet, the platform asks it directly instead — a low-level network query the guest’s operating system answers automatically, with no agent and nothing to install. Only an instance that stays silent and fails to answer, repeatedly, is reported impaired.
  • The reachability check tells you the guest is running, not that your service is. It confirms the instance’s operating system is up and its network stack is responding. An application that has crashed inside a healthy instance will not show up here — that is what your own monitoring, or a load balancer health check, is for.

Reading status and health together

Both come back from the same call, which is the point — status alone never tells you an instance is confirmed working.

GetInstance.graphql
query GetInstance($instanceUrn: Urn!) {
compute {
instance(instanceUrn: $instanceUrn) {
urn
instanceId
instanceType
status
statusReason
healthChecks {
availability
checks {
kind
category
status
since
}
}
}
}
}
Poll until the instance settles
origin compute get-instance \
--instance-urn urn:origin:cloud:compute:eu-central1:7a07d9ec7ba2:proj-4f21c9a03b17:i-RAiXDqjUHLh

When a lifecycle operation fails

Launching, stopping and terminating an instance are all asynchronous: the call returns as soon as the platform has accepted the request, and the instance’s own status — plus statusReason when it failed — is where you find out what happened. If the host can’t carry out what you asked, the instance ends up FAILED — it never silently stays in a transitional state waiting for something that isn’t coming.

FAILED means only one thing: the platform is not able to confirm your instance is where you asked it to be. In particular it does not promise the instance is stopped or gone.

  • A launch that failed. Nothing ever started. Retry with start-instance, or give up with terminate-instance.
  • A stop that failed. The instance may well still be running. start-instance puts it back into the normal running lifecycle (from where you can stop it again), and terminate-instance gets rid of it for good — those are the two ways forward; there is no separate “retry the stop”.
  • A termination that failed partway. The instance stays FAILED rather than reporting TERMINATED, precisely so you aren’t told a resource is gone when the platform couldn’t confirm it. Just call terminate-instance again — termination is always safe to retry. Note that terminating an instance that is already FAILED is the one case that doesn’t wait for the host to confirm: it releases your resources, stops your billing and reports TERMINATED regardless of what the host says, which is what makes “always safe to retry” true. If the host doesn’t do as it’s told on that last attempt, the platform records that for its operators to follow up; from your side the instance is gone and stays gone.

A FAILED instance keeps its network interface and its volumes, stays listed, and never recovers or retries on its own; nothing happens until you start it or terminate it. Because it may still be consuming its host’s capacity, don’t leave one sitting indefinitely — terminate it once you’re done with it.

Why it failed

A FAILED instance also carries a statusReason — a short sentence saying what went wrong, returned by get-instance and list-instances alongside status. It is one of a small set of classifications rather than the underlying host error:

  • the instance could not be started on its host
  • the operation failed (ERR_INSTANCE_START / ERR_INSTANCE_STOP) — the host refused the start, stop or shutdown it was asked for
  • a volume this instance needs could not be created
  • a volume this instance needs could not be attached

The underlying detail — the exact error the host or the storage layer reported, and anything about how the platform’s own machines are laid out — deliberately never leaves the platform’s logs, so statusReason will never name a file path, a storage pool or a host. If the classification isn’t enough to act on, quote the instance id to an operator and they can look the rest up.

statusReason is null for every status other than FAILED, and starting a failed instance again clears it — it always describes the failure the instance is in now, never an older one.

One combination is worth knowing about: an instance that failed before reasons were recorded reads as FAILED with statusReason: null. That only ever means “this failure predates the field” — it never means “we don’t know why”, because every route into FAILED records a reason now.

Choosing a storage backend

When you launch an instance, you choose which kind of storage its volumes use — pvs or host_local:

  • pvs (the default) survives independently of any particular host. You can stop and restart an instance using it with no risk of losing its data.
  • host_local storage lives on the same physical machine as the instance itself, with no guarantee of surviving if that machine were ever taken out of service. Because of that, an instance using host_local storage can only be terminated — it can’t be stopped and restarted. There’s no “stopped, ready to resume” state that would make sense for data that can’t outlive its host, so this instance stays fully reserved (compute and storage) on its host for its entire life, until you terminate it. For the same reason its volumes can’t be snapshotted or resized — those requests are refused, not queued (see the Storage guide).

Use pvs unless you have a specific reason to accept host_local’s tighter coupling to its host — most workloads should use pvs.

Controlling access with security groups

A security group is a firewall for one instance’s network interface: a list of rules describing what’s allowed in and out, by protocol, port, and a source or destination IP range.

Security groups are stateful: once a rule lets a connection start, its reply traffic is allowed automatically — you don’t need a separate rule for the response. Anything not explicitly allowed is denied by default.

Changes to a security group’s rules take effect on every instance using it automatically, typically within a few seconds — you don’t need to restart an instance for a rule change to apply.

Every VPC gets one default security group automatically, and you can create additional ones if you want different rule sets for different instances or workloads rather than editing the one default to fit everyone. A VPC’s default security group can’t be deleted on its own — it goes away only when the VPC itself is deleted — and a non-default security group can’t be deleted while any network interface still has it attached.

Security groups aren’t the only traffic control in the platform — network ACLs apply at the subnet level, above any individual instance’s security groups. See the Network guide for how the two combine.

Using Compute

Everything above is available through:

  • The GraphQL API — the primary interface. Look under the compute namespace for instances, images, and key pairs.
  • The origin CLI — a thin client over the same API. Relevant commands: launch-instance, list-instance-types, start-instance, stop-instance, terminate-instance, list-instances, get-instance, create-image, list-images, get-image, import-key-pair, list-key-pairs, get-key-pair, delete-key-pair.

Launching an instance

A launch is asynchronous: the call returns as soon as the platform accepts the request, and the instance starts at INITIALIZING. A key pair is required — a launch with none is rejected rather than falling back to a shared key.

LaunchInstance.graphql
mutation LaunchInstance($input: ComputeLaunchInstanceInput!) {
compute {
launchInstance(input: $input) {
urn
instanceId
availabilityZone
instanceType
status
createdBy
}
}
}
variables.json
{
"input": {
"projectUrn": "urn:origin:cloud:admin::7a07d9ec7ba2::proj-4f21c9a03b17",
"imageUrn": "urn:origin:cloud:compute:eu-central1:::img-debian-12-base",
"keyPairUrn": "urn:origin:cloud:compute:eu-central1:7a07d9ec7ba2:proj-4f21c9a03b17:key-3c8e11d09f42",
"instanceType": "gp1.core.2",
"volumeBackend": "pvs"
}
}
origin compute launch-instance
origin compute launch-instance \
--project-urn urn:origin:cloud:admin::7a07d9ec7ba2::proj-4f21c9a03b17 \
--image-urn urn:origin:cloud:compute:eu-central1:::img-debian-12-base \
--key-pair-urn urn:origin:cloud:compute:eu-central1:7a07d9ec7ba2:proj-4f21c9a03b17:key-3c8e11d09f42 \
--instance-type gp1.core.2 \
--volume-backend pvs

Omit --subnet-urn to use the project’s default subnet — created on first use, in a VPC that already has an Internet Gateway attached and a public IP auto-assigned to the instance’s interface.

Origin Cloud — user documentation Edit this page →