Skip to main content
Operating System

Resource Limits

Configure bounded VM, process, JavaScript, Python, and WASM resources.

Pass a limits tree in the VM’s configuration. The sidecar applies it when the VM starts. Near-limit pressure is reported as the vm.limitWarning event on a hosted VM, or through onLimitWarning in the library.

Use limits.tls.maxBufferedBytes to bound TLS plaintext buffering. limits.execution.completedTtlMs and limits.execution.maxCompletedExecutions bound retained completed language executions. limits.execution.liveExecutionWarningThreshold sets the live execution count that triggers a warning, not a rejection. These fields are optional; omission keeps the sidecar default.

Process output replay is also sidecar-owned. The defaults retain up to 1,024 events or 1 MiB for each opted-in process, return at most 256 events or 768 KiB per read, and retain at most 1,024 replay records per VM. Override them with limits.process.outputReplayEvents, outputReplayBytes, outputReplayPageEvents, outputReplayPageBytes, and maxOutputReplays. Page limits cannot exceed their corresponding retention limits. Omitting a page bound in process.readOutput uses the VM’s configured limit; explicit zero or a value above the limit is rejected.

Every queue, buffer, timeout, and resource collection has a bounded default. Near-capacity conditions call onLimitWarning; exhausted limits fail with a typed error naming the limit and the field used to raise it.

limits.reactor.shutdownDeadlineMs bounds the SQLite close wait and subsequent resource drain together. Process termination and filesystem flushing happen before this budget. If close exceeds the deadline, VM shutdown reports a typed timeout with the limit name instead of reporting a clean stop. Close completion can no longer be confirmed, so the VM stays quarantined until the sidecar process restarts, even if local resource counts reach zero. Quarantined VMs count toward VM admission capacity.

Limits are fixed for the life of a VM. To change them on a hosted VM, update the config and call v1.vm.restart. In the library, dispose the VM and create a new one with the new limits. The hosted actor also has a fixed ten-second shutdown wait; raising the sidecar deadline does not extend it.

Sidecar limits

Library VMs share a sidecar process by default. Limits that apply to the whole process, such as runtime.executor.maxActiveVms, are set when creating a dedicated sidecar with AgentOs.createSidecar(), as in the example above.

Each library request to the sidecar must fit in one protocol frame. The sidecar reports its frame limit (16 MiB) when the client connects, and the limit is not configurable. The client rejects a larger request with SidecarFrameTooLarge before it sends it, so the sidecar and the other VMs on it keep running. Binary file content is base64-encoded, so one writeFile or writeFiles call carries at most about 12 MiB of binary data. To move larger files, split them into several files or mount a host directory.

Sidecar memory

On Linux with glibc, the sidecar returns memory freed by a disposed VM’s V8 isolates to the OS shortly after disposal.

The sidecar also keeps a pool of up to four pre-started V8 isolates so that JavaScript and Python executions start faster. The pool stays resident while the sidecar runs, at about 20 MiB per isolate. To cap it, set AGENTOS_V8_WARM_ISOLATES to a value from 0 to 4 in the environment that starts the sidecar. 0 disables the pool and trades memory for slower execution starts.

Embedded API

Limits apply to VMs created with AgentOs.create() and sidecars created with AgentOs.createSidecar(). Read more in the embedded API quickstart.