CPU Benchmarking for AI Sandbox Scaling
This guide explains how to benchmark a CPU specifically for running many isolated AI agent sandboxes—environments where each agent runs in its own container or VM. You will learn what to measure, how to design a realistic workload, and how to interpret the results to estimate how many sandboxes your hardware can handle concurrently. You will need a Linux server (or a Linux VM with full CPU access), root or sudo privileges, and a basic familiarity with the command line.
What You’ll Need
- A Linux machine (Ubuntu 22.04 or similar) with a modern x86-64 or ARM64 CPU.
- At least 8 GB of RAM (more if you plan to test many sandboxes).
- Root or sudo access to install packages and change system settings.
- Docker or Podman installed (for container-based sandboxes).
- A tool like
stress-ng,sysbench, orhyperfine(we’ll usestress-ngandsysbench). - A script or command to launch multiple sandboxes (e.g.,
docker run).
Step-by-Step
- Define your sandbox workload. What does a typical agent do? For example, it might run a Python script that does JSON parsing, web requests, and some regex. Write a small script that mimics this. A good generic test is a Python loop that does CPU-bound math (e.g., computing prime numbers) and some I/O (e.g., writing to a temp file). We’ll use a simple CPU-bound Python script as an example.
- Prepare the base image. Create a Dockerfile that installs Python and copies your test script. Build the image once. This ensures every sandbox starts from the same state.
- Measure single-sandbox CPU usage. Run one sandbox with your script and use
timeto measure how long it takes to complete. Also note the CPU percentage it uses (you can usetoporpidstat). This tells you how much of a single core one agent consumes. - Run a controlled multi-sandbox test. Start with a small number, say 4 sandboxes simultaneously. Use a script that launches them in the background and waits for all to finish. Record the total wall-clock time and the CPU utilization (using
mpstat -P ALL 1in another terminal). - Increase the load gradually. Double the number of sandboxes (8, 16, 32, …) and repeat the test. Note the point where the total time starts increasing significantly or where CPU utilization hits 100% on all cores. That is your practical limit for that workload.
- Use a synthetic stress tool for a baseline. Run
stress-ng --cpu $(nproc) --timeout 60sto see if the CPU can sustain all cores at 100% without thermal throttling. Compare the reported BogoOps (or similar) to see if performance degrades over time. - Measure memory and I/O contention. Use
sysbench --test=memory --num-threads=16 runto test memory bandwidth. Also runsysbench --test=fileio --file-total-size=2G prepareand thenrunto test disk I/O. These can become bottlenecks even if CPU is not. - Record your results. Create a table with columns: number of sandboxes, total time, CPU % (average), memory used, and any errors. This becomes your benchmark reference.
- Calculate per-sandbox CPU cost. Divide the total CPU time (sum of all processes’ CPU time) by the number of sandboxes. For example, if 8 sandboxes take 10 seconds and each uses 100% of one core, that’s 8 core-seconds per sandbox. This helps you estimate capacity: if you have 16 cores, you could run ~16 sandboxes of that type concurrently.
- Test with realistic concurrency. If your agents are I/O-bound (waiting on network), they may use less CPU. Simulate that by adding a
sleepin the script. Run the same scaling test to see how many more sandboxes you can run.
Common Mistakes
- Using a synthetic benchmark that doesn’t match your workload. A CPU that scores well on
sysbenchmight still struggle with your specific Python code. Always test with your actual script. - Ignoring memory and disk I/O. Many sandboxes share the same filesystem and memory. If you run out of RAM, the system swaps and performance collapses.
- Not accounting for hyperthreading. On Intel/AMD CPUs with SMT, 16 logical cores might not give 16x performance for CPU-bound tasks. Test with
stress-ngto see the real scaling. - Forgetting about thermal throttling. A short test may not reveal that the CPU slows down after 10 minutes of full load. Run a longer test (at least 5 minutes) to see sustained performance.
- Overlooking container overhead. Starting many containers has a cost. If your sandboxes are short-lived, the startup time might dominate. Measure the time to start a container separately.
Tips
- Use CPU pinning. If you have a specific number of cores, pin each sandbox to a core using
tasksetor Docker’s--cpuset-cpusto avoid context-switching overhead. - Set CPU limits. Use Docker’s
--cpusto limit each sandbox to a fraction of a core. This allows you to run more sandboxes than cores, but each will be slower. Benchmark different limits to find the sweet spot. - Monitor with a tool like
htoporperf. This helps you see which processes are consuming CPU and whether any are waiting on I/O. - Test on the same hardware you’ll use in production. If you’re benchmarking on a dev laptop, results won’t transfer to a cloud instance with different CPU and memory.
- Repeat each test 3 times and take the median. This reduces noise from background processes.
Troubleshooting
- CPU usage doesn’t reach 100%. This means your workload is not CPU-bound. Check if it’s waiting on disk or network. Use
iostatandnetstatto see. If so, adjust your test to include more CPU work or accept that your bottleneck is elsewhere. - System becomes unresponsive during the test. You likely ran out of memory or caused heavy swapping. Reduce the number of sandboxes or add more RAM. Also check
dmesgfor OOM-killer messages. - Results are inconsistent between runs. Background processes, other users, or CPU frequency scaling can cause variation. Close unnecessary programs, use
cpupower frequency-set --governor performanceto lock the CPU frequency, and run tests at a quiet time. - Docker containers fail to start when scaling up. This could be due to hitting the PID limit or inotify limits. Check
cat /proc/sys/kernel/pid_maxandfs.inotify.max_user_instances. Increase them if needed. - Benchmark shows high CPU but low throughput. Your sandboxes might be doing a lot of busy-waiting or polling. Look at your code for inefficient loops. A profiler like
py-spycan show where time is spent.
Frequently Asked Questions
How many sandboxes can I run per core?
It depends on your workload. If each sandbox uses 100% of a core, you can run about one per core. If it uses 50%, you can run two. Measure your specific script’s CPU usage to estimate.
Should I use containers or VMs for sandboxes?
Containers have less overhead and start faster, so they are usually better for many small sandboxes. VMs provide stronger isolation but use more resources. Benchmark both if isolation is critical.
Does CPU cache size matter for sandboxes?
Yes. If your workload fits in L3 cache, it will run faster. When many sandboxes run, they share the cache, which can cause contention. Test with your actual workload to see the impact.
How long should my benchmark run?
Run long enough to reach steady state. For CPU-bound tasks, 5 minutes is usually enough. For I/O-bound tasks, 10 minutes or more may be needed. Watch for thermal throttling after 10+ minutes.
What if my CPU has many cores but low single-thread performance?
If your sandbox workload is single-threaded, you’ll benefit from more cores, not faster ones. If it’s multi-threaded, a mix of both is ideal. Benchmark with your actual script to see which matters more.
Can I use cloud CPU benchmarks from the vendor?
Vendor benchmarks are a starting point, but they don’t reflect your specific workload. Always run your own test on the exact instance type you plan to use.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.