docs/sandboxes/optimization.mdx
There is no single fastest setup. Start with the defaults, measure your workload, and change one setting at a time.
Run these commands before tuning anything:
msb doctor
msb inspect worker
msb doctor checks host capabilities. msb inspect shows the settings that a sandbox actually uses.
| If you want to | Start with |
|---|---|
| Create OCI sandboxes faster | A flat root disk with clone=auto |
| Spread CPU-heavy work across physical cores | cpu_placement: spread |
| Favor cache locality | cpu_placement: compact |
| Tune large memory mappings | Keep THP at madvise, then benchmark always |
| Control buffered disk pressure on Linux | Keep block writeback at auto |
The default layered root shares OCI layers between sandboxes. A flat root turns the image into one ext4 disk and clones it for each sandbox. This can improve creation time and filesystem-heavy workloads on hosts with copy-on-write cloning.
msb pull python:3.12 --materialize flat
msb create python:3.12 --name worker --root-disk flat:8G,clone=auto
clone=auto uses a native copy-on-write clone when available and falls back to a sparse copy. Use the layered root when image layer sharing or maximum portability matters more.
See OCI images for image behavior and Bootstrap for flat root details.
By default, sandbox vCPU threads follow the host scheduler. On Linux and Windows, microsandbox can place those threads for you.
| Policy | What it does |
|---|---|
inherit | Leaves placement to the host scheduler. This is the default. |
auto | Uses available physical cores first, then shares CPUs when needed. |
spread | Spreads work across physical cores. |
compact | Keeps work on fewer physical cores for better cache locality. |
Start with auto on a dedicated host. Use spread for CPU-heavy throughput work. Use compact when cache locality or packing more sandboxes onto a host matters most.
import { Sandbox } from "microsandbox";
await using sb = await Sandbox.builder("worker")
.image("python:3.12")
.cpus(2)
.cpuPlacement("spread")
.create();
use microsandbox::sandbox::{CpuPlacement, Sandbox};
let sb = Sandbox::builder("worker")
.image("python:3.12")
.cpus(2)
.cpu_placement(CpuPlacement::Spread)
.create()
.await?;
from microsandbox import CpuPlacement, Sandbox
sb = await Sandbox.create(
"worker",
image="python:3.12",
cpus=2,
cpu_placement=CpuPlacement.SPREAD,
)
sb, err := m.CreateSandbox(ctx, "worker",
m.WithImage("python:3.12"),
m.WithCPUs(2),
m.WithCPUPlacement(m.CPUPlacementSpread),
)
Large hosts can have more than one NUMA node. A placement profile can keep a sandbox's CPU and memory on the same node.
First, define a named profile in the global config:
{
"runtime": {
"placement_profiles": {
"latency": {
"numa": { "mode": "prefer_single" },
"memory": { "mode": "follow_cpu" }
}
}
}
}
Then select it when you create the sandbox:
msb create python:3.12 \
--name worker \
--cpus 2 \
--cpu-placement auto \
--placement-profile latency
prefer_single uses one node when enough CPU and memory are available. Otherwise, it falls back to normal placement. Use strict_single when the sandbox should fail instead of falling back.
MSB_HOME.inherit because hard CPU affinity is not available through a public API.inherit. A strict_single profile fails instead.Use msb inspect worker to see the resolved policy and placement result.
Transparent huge pages, or THP, control how the guest handles large memory mappings.
| Policy | Use it when |
|---|---|
madvise | You want the safe default |
always | Benchmarks show a gain for large, sustained mappings |
never | Predictable small-page behavior matters more |
THP changes take effect the next time the sandbox boots. Keep madvise unless real workload tests show a clear improvement.
On Linux, block writeback limits how much buffered disk data active sandboxes can hold in host memory.
auto chooses safe limits from the host. This is the recommended setting.fixed uses limits that you provide.off disables the limits for new sandboxes.This setting has no effect on non-Linux hosts, read-only disks, or direct I/O. See Global config for the available fields.
On Linux x86 hosts, AMD AVIC and Intel APICv can make virtual interrupt delivery faster. These are host KVM settings, not sandbox settings.
Check their status with msb doctor. Read Linux troubleshooting before changing a KVM module because the change affects every VM on the host.
microsandbox automatically selects compatible filesystem, guest kernel, interrupt, and vCPU affinity optimizations. These implementation details do not have user-facing settings.
Keep the image, CPU and memory limits, storage, host power settings, and concurrency unchanged while comparing settings. Measure sandbox creation separately from workload performance.