Resources and health
This page shows how to change the CPU, memory, and disk of a Workspace, which task and memory limits apply inside the guest, how to tell whether the guest still responds or is stuck on memory, and how to read resource metrics over time.
Adjusting resources
kibo workspace update changes the resources a WorkspaceA complete Linux environment for an AI Agent, running in its own MicroVM. Agents read and write files, run processes, and start services in it without affecting the host or other Workspaces. requests. Give at least one of --cpu, --memory, and --disk. Values use the same format as create and are final values, not increments.
Stop the Workspace, change its resources, and start it again:
kibo workspace stop "$workspace_id"
kibo workspace update "$workspace_id" --cpu 2 --memory 4G --disk 40G
kibo workspace start "$workspace_id"--cpuand--memoryonly update the configuration and take effect at the next start. A successful command means the new values are saved; it does not guarantee enough node capacity at the next start. If a start fails for lack of capacity, lower them with this command and try again.--diskenlarges the writable layer right away, keeping its content. When the storage that holds the layer cannot fit the new size, the command fails withresource_exhaustedand the capacity is unchanged.
To change the network policy, use kibo workspace network. See Network policy.
When you can update
The Workspace must hold no execution. The table shows what to do first in each case:
| Workspace | Before update |
|---|---|
STOPPED | Nothing |
FAILED, no longer holding an execution, and never begun deletion, whatever stage the failure happened in | Nothing |
| Running | Run kibo workspace stop. Otherwise update exits with code 13 |
FAILED, still holding an execution | Run kibo workspace stop --force. See Force stop |
| Deletion has begun | The resources cannot change. The only option is to run kibo workspace delete again |
CPU and disk values
- The number of vCPUs an instance gets is the millicores divided by a thousand, rounded up:
1.5gets 2 vCPUs, and0.5gets 1. The node that hosts the instance decides at start time how many vCPUs a single instance can get. --disksets the capacity of the writable layerThe writable part of a Workspace's root file system, holding changes such as installed packages; Operator pages call it the retained layer. It is kept on a best-effort basis, and only the Volume is guaranteed to keep data.. It can only grow, and all existing content is kept. A value equal to the current capacity does nothing. A value below the current capacity returnsinvalid_argument.- For a Workspace that has never started, the disk capacity is only recorded, and the writable layer is created with it at the first start. The Disk line of
kibo workspace getsayscreated at first startwhile the writable layer does not exist yet, and shows both values when the requested and actual capacities differ.
Partial results
On the server, memory, CPU, and the writable layer are three independent commands. No atomic operation changes several at once. update submits only the items you give, in the order memory, CPU, disk:
| Case | Result |
|---|---|
| All succeed | Prints the final Workspace and the result of each item, exits 0 |
| The first item fails | Nothing changes. Exits according to the failure, for example 13 for a running Workspace |
| An item fails after earlier items took effect | Lists each item as applied, failed, or not submitted, does not submit the remaining items, exits 17 |
| An item's result is unknown | Exits 18 and gives that item's command ID |
Revisions and replays
CPU and memory are checked against one shared resources revision; disk is not. The rules:
- When
--expected-revisionis not passed,kiboreads the current revision before submitting. If the revision has changed by submission time,updatereturns a conflict and does not retry automatically. - Setting the same value does not change the revision.
- For a script that needs to replay, pass
--command-idtogether with--expected-revision. Each item's command ID is that value plus/memory,/cpu, or/disk.
For the API methods behind each item, see Changing resources.
Limits inside the guest
The guestThe Linux system that runs inside the MicroVM of a Workspace. The guest agent in it performs file and process operations for the node. reserves part of the task count and memory for the kernel and platform processes. When user processes use up their share, file operations, process management, and stopping keep working.
Tasks
Each process and each thread counts as one task. Two limits apply:
| Scope | Limit | When it is used up |
|---|---|---|
| All processes in the Workspace | 256 + 32 × CPU count below the kernel limit. The rest is reserved for kernel threads and guest programs | Creating new processes and threads fails (EAGAIN) in every process, and ProcessService/Start returns resource_exhausted, which you can retry |
Each process started by ProcessService/Start, together with its descendants, and the desktop | At most 3/4 of the total above | Creating new processes and threads in it fails (EAGAIN). A runaway process stops there, and other processes still start |
Memory
- The total memory all processes in the Workspace can use is somewhat below the memory available when the guest boots. The difference, 1/16 of memory kept between 64 MiB and 256 MiB, is reserved for guest programs and the kernel.
- When the total is used up, the kernel ends the process using the most memory, and other processes keep running.
- When processes stay stalled waiting for memory, the guest also ends the largest one. See Memory saturation.
System files
The guest rewrites /etc/hostname, /etc/hosts, and /etc/resolv.conf at every boot. Changes to them made in the guest, including added immutable or append-only attributes, do not persist across boots.
Responsiveness of the guest
A running Workspace carries a guest observation. The node that runs it probes the guest periodically. Several timeouts or connection failures in a row mark the guest as no longer responding, and one response clears it.
List the Workspaces whose guest no longer responds to its node, then look at one of them:
kibo workspace list --guest-unresponsive
kibo workspace get "$workspace_id"- The GUEST NOT RESPONDING section at the end of the
listoutput gives the time each guest stopped responding and its latest error. - The Guest line of
getshows the same observation. If the guest has reset itself, it also shows the restart count and the time of the latest reset.
What the observation means
- It is an observation, not a state. When the guest stops responding, the Workspace is still
AVAILABLE. Admission and expiration reclamation ignore the observation, and the guest may recover on its own. Data-plane requests keep timing out in the meantime. The same holds if the guest happens not to respond when the node restarts. - When it is absent. A Workspace with no running instance (for example,
STOPPED) does not carry it. It is also absent before the node has reported and while the guest is rebooting itself. - After the guest reboots itself. Once the guest answers again, the observation says that the guest rebooted. The restart count, the number of times in this execution that the guest reset itself and the node replaced the VMM, goes up by 1, and the time of the latest reset is the time of this one. The next execution starts the count from 0.
- How soon you see it. It usually shows up within 2 minutes of the guest getting stuck.
Recovering an unresponsive guest
The guest may recover on its own. For a guest that never recovers, reclaim it with a force stop, then start it:
Warning
A force stop does not wait for the guest to stop writing. Writes the guest has not flushed may be lost. See Force stop.
kibo workspace stop --force "$workspace_id"
kibo workspace start "$workspace_id"Memory saturation
A responsive guest does not mean its processes are doing work. The guest has no swap. When processes together reach the memory limit, the kernel can always reclaim a little from the processes' own file pages (code and files they read). It keeps reclaiming and reading back, and the OOM killer never fires. Processes nearly stall, possibly for hours, while the guest still answers probes.
The guest observation reports this case as a memory condition. The Guest memory line of kibo workspace get shows it:
| Shown | Meaning |
|---|---|
normal | The guest tracks memory pressure, and processes are not pinned at the limit |
saturated at the memory limit since … | Over a recent sustained period, all processes spent most of their time stalled waiting for memory |
unknown | Unknown, which is not the same as normal. The Platform the Workspace uses or the node does not support this report, or the guest no longer responds |
Detection and killing ship with the Platform. A Workspace has them only after it uses a Platform with this report; before that, the memory condition is unknown, and the guest does not end processes. The Firecracker guest kernel tracks memory pressure only when booted with psi=1, and the Firecracker Platform in this release already includes it.
How saturation is judged
- The measure. The guest uses the share of the last 60 seconds during which all processes were stalled waiting for memory at the same time. At 25% or more, the guest marks it saturated. Below 10%, it clears.
- What does not count. A short memory peak does not fill the window and is not marked as saturation. When memory is full but processes are not stalled waiting for it, as in an idle Workspace, the share is close to 0.
- It is also an observation. Saturation does not change the Workspace's state, admission, or expiration reclamation. It clears on its own once demand drops. If it never clears, the guest ends processes by the rules in the next section.
- How soon you see it. It usually shows up within 2 minutes of processes starting to stall. Clearing also waits for the stall share in the window to drop.
Killing processes under saturation
When saturation persists, the guest sends SIGKILL to the process using the most memory so the remaining processes can continue.
- When it kills. All three conditions hold:
- Saturation has lasted 90 seconds.
- The share in the current 60-second window is still at least 25%. If the share has fallen below 25%, the guest takes no action: it is still reported as saturated but can make progress.
- Processes actually hit the memory limit during this time. A stall without hitting the limit means the whole guest is short of memory, and the kernel's OOM killer handles it.
- Which process. The managed process with the largest resident memory (RSS). The guest agent and platform processes are not candidates and are never chosen. Only this one process is ended. Its children and other processes in the same session are not affected unless they exit along with it.
- Afterward. No action is taken during a 60-second cooldown. If the three conditions above still hold when the cooldown ends, the next process is ended by the same rules.
- How to tell. The ended process exits as killed by signal 9, which looks the same as a kernel OOM kill.
kibo workspace getshows an extra Guest memory kills line with the count, the latest ended process, and the reason. The guest log and the node log each have a record. - How long the count lasts. The kill count and the latest ended process reset when the guest reboots. They are kept while the guest does not respond, and disappear after the Workspace stops.
Cases killing cannot fix
- Memory in tmpfs (
/tmp,/run,/dev/shm) belongs to no process, and ending processes does not free it. - Thrashing whose share stays below 25% is not marked as saturation, so no action is taken.
Recover from either case with a force stop and a start, or increase memory.
Reading resource metrics
kibo workspace metrics shows a Workspace's resource readings over time, by default for the last hour. The deployment must have connected instance metrics storage for reads. Otherwise kibo stops before reading; see Resource metrics for the capability it checks.
Read the last 24 hours, or a fixed range as JSON:
kibo workspace metrics ws-0123 --since 24h
kibo workspace metrics ws-0123 --start 2026-11-06T08:00:00Z --end 2026-11-06T09:00:00Z --jsonHost and guest readings
The readings come in two series, each in buckets of one step:
| Series | Read from | Fields | Can the guest alter it? |
|---|---|---|---|
host | The host, outside the guest | cpu_cores, memory_bytes, the five pressure ratios, and network bytes, packets and drops per second in each direction | No. It continues while the guest does not answer |
guest | Inside the guest | The seven values of the E2B sandbox metrics: CPU count and use, memory total, used and cache, disk total and used | Yes, root in the guest can. It has no points while the guest does not answer |
Buckets
ctrl picks the step from the length of the range, end − start:
| Range | Step |
|---|---|
| Under 1 hour | 5 seconds |
| Under 6 hours | 30 seconds |
| Under 12 hours | 1 minute |
| Under 24 hours | 2 minutes |
| Under 7 days | 5 minutes |
| Longer | 15 minutes |
- Rates (
cpu_cores, the pressure ratios, the network fields) are averages over the bucket: a rate times the step is the bucket's total. Levels (memory_bytesand every guest field) are the bucket's highest value. - Every execution of the Workspace is merged into one series, also when it was stopped and started on another node. Nothing is filled in between two executions.
- A host point carries only the fields the storage has samples for. A guest point is returned only when all seven values are present.
- A range that would need more than 4,000 buckets is refused with
invalid_argument. Narrow it with--startand--end.
Retention and gaps
- How far back readings reach depends on the storage's retention. Do not assume a fixed length; copy readings elsewhere if you need a longer history.
- Readings are observations, not usage records. They have gaps when the storage is unreachable, the guest does not answer, or a node restarts.
- A deleted Workspace stays readable while the storage still holds its readings. A Workspace with no readings returns two empty series.
With the API
This section lists the methods, fields, and capabilities behind the kibo commands above.
Changing resources
kibo workspace update maps to three methods: UpdateWorkspaceMemory, UpdateWorkspaceCpu, and ResizeWorkspaceWritableLayer. The rules in Adjusting resources apply to each of them.
- Memory and CPU use optimistic locking and share one resource revision,
resources_revision. - Growing the writable layer has no expected revision, only a command ID and a target capacity.
Guest observation
A Workspace's guest_observation carries the observation described in Responsiveness of the guest and Memory saturation. Its capability name is workspace.guest_observation. For every field, see GuestObservation.
conditionisGUEST_CONDITION_RESPONDINGorGUEST_CONDITION_UNRESPONSIVE.rebooted,restart_count, andlast_reset_atdescribe the guest's own reboots.memory_conditionisGUEST_MEMORY_CONDITION_NORMAL,GUEST_MEMORY_CONDITION_SATURATED, orGUEST_MEMORY_CONDITION_UNSPECIFIED, whichkiboshows asnormal,saturated at the memory limit since …, andunknown.memory_kill_countandlatest_memory_killdescribe the processes the guest ended under saturation.
guest_condition on ListWorkspaces returns only Workspaces whose current observation has that value:
- You can combine it with
statesandlabel_selector. - When paging, it must match the request that produced the cursor.
- Older servers ignore
guest_conditionand return all Workspaces. Confirm that the capabilityworkspace.guest_observationexists before filtering.
Resource metrics
kibo workspace metrics maps to WorkspaceMetricsService/GetWorkspaceMetrics. The deployment must connect instance metrics storage for reads and announce workspace.metrics.get; kibo checks this capability before calling the method. For the request and response, see WorkspaceMetricsService.
- The response carries the step it used, and
earliest_time, the earliest time the storage still holds. - When the storage does not answer in time, the method returns
unavailable. - When too many reads are in progress, it returns
resource_exhaustedat once. Other methods are not affected. - An ID ctrl has never known returns
not_found.
Troubleshooting
Data-plane requests keep timing out
- Symptom: The Workspace is
AVAILABLE, but running commands and reading or writing files time out. - Cause: The guest no longer responds. Confirm with
kibo workspace list --guest-unresponsiveorkibo workspace get. - Fix: The guest may recover on its own. If it never recovers, force stop and then start.
Processes nearly stalled
- Symptom: The guest responds and commands run, but application processes make almost no progress for a long time, or they are ended by signal 9.
- Cause: Processes together reached the memory limit. The Guest memory line of
kibo workspace getshowssaturated…, or a Guest memory kills line appears. - Fix: Reduce the load, or stop the Workspace and increase memory. If tmpfs fills memory, clean up files in
/tmp,/run, and/dev/shm. If commands no longer run either, force stop and then start.
Next steps
- Lifecycle: force stops and reboots from inside the guest.
- Commands and terminals: running processes in the guest.
- Instance metrics storage: connecting the storage that
kibo workspace metricsreads. - API overview: calling these methods from your own program.
Volumes, export, and restore
A Volume stores a Workspace's data and exists independently of any Workspace. This page shows how to choose a Volume when you create a Workspace, create and resize Volumes, rebind them, and export a Workspace's data to restore it as a new Workspace.
Expiration
An expiration time makes ctrl stop or delete a Workspace automatically when it arrives. This page shows how to set, change, and clear it, at creation, on its own, or together with start and stop.