Affected component
Select:
Orchestrator / sandbox lifecycle
Problem statement
AgentENV does not provide a supported way to change the host CPU affinity of a running sandbox. This is needed for performance analysis and hardware characterization, where reproducible placement of Firecracker vCPU threads is important.
Today, an operator has to identify the compute node that owns the sandbox, correlate the sandbox with an internal Firecracker process, enumerate its threads through host process information or /proc, and invoke taskset or sched_setaffinity manually. This is unreliable and depends on internal implementation details. It also requires shell access to the exact compute node, so it cannot be used reliably through the AgentENV gateway in a multi-node deployment.
The requested capability is a sandbox-level API and CLI operation that binds selected Firecracker threads to specified host logical CPU IDs while keeping the Firecracker PID and TIDs internal to the compute node.
Use case
I am a hardware architect evaluating processor designs for agent workloads. We use AgentENV sandboxes for microbenchmarking and workload characterization on hosts with more than 100 logical CPUs. A typical session runs dozens of sandboxes and may change affinity before every benchmark run, often dozens of times per day.
The main use cases are:
- Topology-aware performance optimization. Select logical CPUs according to LLC, NUMA, and SMT topology to improve the performance of long-running workloads.
- Stable measurements. Prevent vCPU threads from migrating across many host CPUs so that PMU counters, IPC, cache-miss rates, and latency measurements have less run-to-run noise.
- Controlled oversubscription. Place multiple vCPU threads on the same logical CPU, or on sibling logical CPUs of one physical core, to evaluate oversubscription behavior.
Current behavior and workarounds
There is currently no AgentENV API or CLI operation for changing CPU affinity after a sandbox has started.
The manual workaround is to:
- Determine which compute node owns the sandbox.
- Correlate the sandbox with its internal Firecracker process.
- Enumerate the Firecracker TIDs, for example with
ps or /proc/<pid>/task.
- Apply
taskset or sched_setaffinity to individual TIDs.
For example, a Firecracker process can contain threads such as:
TID COMMAND
831624 firecracker
831628 fc_api
973593 fc_vcpu 0
973594 fc_vcpu 1
973595 kvm-nx-lpage-re
This workaround is insufficient because:
- process and thread IDs are internal, short-lived identifiers and may be reused;
- locating the process through internal log paths is unreliable;
- the operation requires host shell access and usually elevated permissions;
- it cannot be routed through the gateway to a remote compute node;
- malformed or extremely large CPU ranges can cause excessive resource use in a naive implementation;
- offline or unsupported CPU IDs are not handled consistently; and
- applying affinity thread by thread can leave a partially updated sandbox when an operation fails.
Desired behavior
AgentENV should provide an authenticated sandbox operation that changes CPU affinity on the compute node currently running the sandbox.
Acceptance criteria:
- A user can select one or more Firecracker vCPU indexes, such as
0, 0-3, or 0-10:2.
- A wildcard selector,
*, targets every thread currently belonging to the Firecracker process, including non-vCPU helper threads.
- A user can specify a taskset-like list of host logical CPU IDs, including lists, ranges, and range strides.
- The compute node resolves the Firecracker PID and TIDs internally; the public API does not expose them.
- The operation is accepted only for a running sandbox and is routed to the compute node that owns it.
- User-controlled CPU lists are length- and range-bounded before expansion.
- Requested host CPUs are checked against online CPUs. Offline CPUs may be reported as ignored, but the operation fails when the online intersection is empty.
- The operation verifies the applied affinity and does not silently report success when only part of the request was applied.
- If a thread update fails, earlier changes are rolled back where possible and rollback failures are reported. The operation is best-effort transactional because Linux does not provide an atomic multi-thread affinity syscall.
- The response reports the normalized CPUs that were applied, ignored offline CPUs, and the number of bound threads.
- When the feature is disabled by node configuration, the compute node returns a clear error without modifying affinity.
Proposed approach
Add a sandbox API operation such as:
POST /sandboxes/{sandboxID}/cpu-affinity
Content-Type: application/json
{
"vcpu": "0-1",
"core": "4-7"
}
Add a corresponding CLI command:
aenv cpu-bind <sandbox-id> --vcpu 0-1 --core 4-7
aenv cpu-bind <sandbox-id> --vcpu '*' --core 4-7
The orchestrator should perform lifecycle validation and serialize the operation with other sandbox lifecycle operations. The compute-node sandbox backend should obtain the PID from the Firecracker child process it already owns. A low-level affinity module should enumerate threads, select targets, validate CPU lists, apply and verify affinity, and perform best-effort rollback on failure.
The PID is an internal implementation detail and should not be added to the public API, CLI, metadata, or persistent sandbox records.
I have implemented a working prototype in the following branch and can adapt it based on maintainer feedback:
https://github.com/emailcannotbeblank/AgentENV/tree/feature/bind-cpu
Compatibility and operational impact
API/config changes:
- Adds one sandbox CPU-affinity endpoint and corresponding request/response models.
- Adds an
aenv cpu-bind CLI command and SDK client method.
- The prototype adds
sandbox.cpu_affinity_enabled as a node-level switch: 1 enables CPU binding, while 0 disables it and causes the compute node to reject the operation immediately. The current default is 1.
- The switch is node-wide rather than per-user. Operators can enable the feature only on nodes or deployments intended for trusted advanced users. Disabling it reduces exposure of host CPU-topology information and prevents unauthorized or accidental affinity changes from degrading the performance of other users' workloads. Per-user authorization, if required, must be enforced by the deployment's API authorization layer.
- Existing sandbox APIs and clients remain unchanged unless the new operation is called.
Snapshot or storage format changes:
- None. No snapshot manifest, sandbox metadata, database, artifact layout, or storage format is changed.
New host/runtime requirements:
- Linux CPU-affinity syscalls must be available.
- The AgentENV runtime user must be allowed to change the affinity of the Firecracker process it owns.
- The current prototype supports host logical CPU IDs
0-1023, matching the fixed-size cpu_set_t used by the implementation.
- No public PID access and no additional host package are required.
Upgrade and rollback considerations:
- The gateway, compute-node server, generated API code, SDK, and CLI should be upgraded together when the new operation is required through a cluster deployment.
- Older nodes or gateways will not recognize the new endpoint and may return
404.
- Applied affinity is Linux process state. It remains in effect until changed or until the Firecracker process exits.
- Runtime affinity is not persisted across pause/resume, sandbox restart, migration, or process recreation.
- Rolling back to an older AgentENV binary removes the API but does not reset affinity on an already-running Firecracker process.
Documentation status:
- The prototype does not yet include comprehensive user and operator documentation.
- If the maintainers agree to add this feature, the pull request will include detailed documentation covering the configuration switch, API and CLI usage, permissions and security considerations, CPU-list syntax and limits, thread-selection semantics, error handling, and lifecycle behavior.
Alternatives considered
- Expose the Firecracker PID and let users run
taskset. Rejected because it leaks an unstable implementation detail, requires access to the exact compute node, is difficult to route through the gateway, and creates PID/TID reuse races.
- Manage the whole sandbox through a cpuset cgroup. This may be valuable for stronger group-level isolation, but it is a larger lifecycle and host-resource-management change. It also does not by itself provide per-vCPU placement.
- Configure affinity only when the sandbox starts. This does not support iterative benchmark workflows that need to change placement repeatedly without recreating the sandbox.
- Keep using host scripts. This is not suitable for a multi-node API-driven platform and cannot provide consistent validation, error reporting, or rollback.
Non-goals
- Exposing Firecracker PIDs or TIDs through the public API or CLI.
- Providing exclusive CPU reservation or preventing unrelated host processes from using the selected CPUs.
- Automatically choosing CPUs based on NUMA, LLC, SMT, or other topology information.
- Changing scheduler capacity accounting or placement decisions.
- Persisting affinity across pause/resume, restart, migration, or Firecracker process recreation.
- Binding arbitrary guest processes or arbitrary host processes.
- Providing hard real-time scheduling guarantees.
Contribution
Select:
I have a working implementation in my fork and can update the code, tests, generated API files, and documentation after the API and scope are agreed upon.
Pre-submission checklist
Affected component
Select:
Problem statement
AgentENV does not provide a supported way to change the host CPU affinity of a running sandbox. This is needed for performance analysis and hardware characterization, where reproducible placement of Firecracker vCPU threads is important.
Today, an operator has to identify the compute node that owns the sandbox, correlate the sandbox with an internal Firecracker process, enumerate its threads through host process information or
/proc, and invoketasksetorsched_setaffinitymanually. This is unreliable and depends on internal implementation details. It also requires shell access to the exact compute node, so it cannot be used reliably through the AgentENV gateway in a multi-node deployment.The requested capability is a sandbox-level API and CLI operation that binds selected Firecracker threads to specified host logical CPU IDs while keeping the Firecracker PID and TIDs internal to the compute node.
Use case
I am a hardware architect evaluating processor designs for agent workloads. We use AgentENV sandboxes for microbenchmarking and workload characterization on hosts with more than 100 logical CPUs. A typical session runs dozens of sandboxes and may change affinity before every benchmark run, often dozens of times per day.
The main use cases are:
Current behavior and workarounds
There is currently no AgentENV API or CLI operation for changing CPU affinity after a sandbox has started.
The manual workaround is to:
psor/proc/<pid>/task.tasksetorsched_setaffinityto individual TIDs.For example, a Firecracker process can contain threads such as:
This workaround is insufficient because:
Desired behavior
AgentENV should provide an authenticated sandbox operation that changes CPU affinity on the compute node currently running the sandbox.
Acceptance criteria:
0,0-3, or0-10:2.*, targets every thread currently belonging to the Firecracker process, including non-vCPU helper threads.Proposed approach
Add a sandbox API operation such as:
Add a corresponding CLI command:
The orchestrator should perform lifecycle validation and serialize the operation with other sandbox lifecycle operations. The compute-node sandbox backend should obtain the PID from the Firecracker child process it already owns. A low-level affinity module should enumerate threads, select targets, validate CPU lists, apply and verify affinity, and perform best-effort rollback on failure.
The PID is an internal implementation detail and should not be added to the public API, CLI, metadata, or persistent sandbox records.
I have implemented a working prototype in the following branch and can adapt it based on maintainer feedback:
https://github.com/emailcannotbeblank/AgentENV/tree/feature/bind-cpu
Compatibility and operational impact
API/config changes:
aenv cpu-bindCLI command and SDK client method.sandbox.cpu_affinity_enabledas a node-level switch:1enables CPU binding, while0disables it and causes the compute node to reject the operation immediately. The current default is1.Snapshot or storage format changes:
New host/runtime requirements:
0-1023, matching the fixed-sizecpu_set_tused by the implementation.Upgrade and rollback considerations:
404.Documentation status:
Alternatives considered
taskset. Rejected because it leaks an unstable implementation detail, requires access to the exact compute node, is difficult to route through the gateway, and creates PID/TID reuse races.Non-goals
Contribution
Select:
I have a working implementation in my fork and can update the code, tests, generated API files, and documentation after the API and scope are agreed upon.
Pre-submission checklist