Agents that generate GPU kernels need to compile, test, and iterate on Metal code without monopolizing the host GPU or crashing when concurrent sessions compete for command queues. Metal Sandbox addresses this by isolating file workspaces, scheduling command execution across a pool of Apple Silicon nodes, and migrating eligible commands to idle machines when local capacity is saturated.
The paper (arXiv 2611.17294v1) reports 1.68× to 2.05× command throughput gains on four Mac mini M4 nodes under concentrated demand, and 22.3% reductions in batch elapsed time when dynamic scheduling replaces static assignment.
The Problem: GPU Resource Contention in Agent Loops
A typical GPU coding agent alternates between three phases:
- Model inference to generate candidate kernel code.
- Metal compilation via
xcrun metalor similar toolchain commands. - Kernel execution to measure performance or correctness.
Each phase touches the GPU differently. Inference saturates compute units. Compilation spawns CPU-bound toolchain processes but may trigger shader validation on the GPU. Execution submits command buffers that block until the GPU finishes.
When multiple agents share one Mac, naive scheduling leads to:
- Queue head-of-line blocking: a long compilation stalls all other agents.
- GPU state pollution: a crashed kernel can leave the Metal driver in an undefined state.
- Workspace collisions: agents overwrite each other’s intermediate
.metallibfiles or test harnesses.
Architecture: Per-Instance Isolation and Cross-Node Scheduling
Metal Sandbox provides three layers:
1. Workspace Isolation
Each agent session gets a private directory tree:
/sandbox/agent-<uuid>/
src/ # generated .metal files
build/ # compiled .metallib artifacts
test/ # execution harnesses
logs/ # stdout/stderr from commands
File access is restricted via macOS sandbox profiles. An agent cannot read or write outside its assigned prefix. This prevents one session from corrupting another’s build artifacts or leaking intermediate results.
2. Command-Level Scheduling
Commands fall into two categories:
- Parallel: compilation, static analysis, or any CPU-bound task that does not require exclusive GPU access.
- Serial: kernel execution that submits Metal command buffers and waits for GPU completion.
The scheduler maintains one serial execution slot per node. Parallel commands run concurrently up to a configurable limit (typically matching CPU core count). When a serial command arrives and the local slot is occupied, the scheduler can:
- Queue it locally and wait.
- Migrate it to another node with an idle serial slot.
Migration copies the agent’s workspace snapshot to the remote node, executes the command, and returns results (exit code, stdout, stderr, modified files) to the originating agent.
3. Harbor Integration
Harbor is the workflow orchestration layer. It:
- Accepts agent requests (tool calls) and routes them to the scheduler.
- Tracks command dependencies (e.g., execution depends on successful compilation).
- Collects rollout data: command durations, GPU utilization, error rates.
- Triggers automatic verification (unit tests, performance benchmarks) after each kernel generation.
Harbor exposes a REST API. Agents submit commands as JSON payloads:
{
"agent_id": "uuid",
"command": "xcrun metal -o kernel.metallib kernel.metal",
"type": "parallel",
"workspace": "/sandbox/agent-uuid"
}
The scheduler returns a handle. The agent polls or subscribes to a webhook for completion.
Scheduling Primitives and Migration Logic
The scheduler uses a two-level queue:
| Queue Type | Scope | Policy |
|---|---|---|
| Local | Per-node | FIFO for serial, concurrent for parallel |
| Global | Cross-node | Work-stealing for eligible commands |
Eligibility for migration: a command can migrate if:
- It has no local file dependencies beyond its workspace snapshot.
- The workspace size is below a threshold (default 100 MB).
- The target node has an idle serial slot or lower parallel load.
Migration cost model: the scheduler estimates:
migration_cost = snapshot_size / network_bandwidth + remote_queue_wait
local_cost = local_queue_wait
If migration_cost < local_cost, the command migrates.
Failure handling: if a remote execution crashes (GPU hang, kernel panic), the scheduler:
- Marks the node as degraded.
- Resubmits the command to another node or the local queue.
- Logs the failure for observability.
The agent sees a retry, not a crash. The host process remains stable.
Observability Hooks
Metal Sandbox exposes metrics via Prometheus endpoints:
metal_command_duration_seconds{type, node}: histogram of command execution time.metal_gpu_utilization{node}: sampled GPU active time fromioreg.metal_compilation_failures{node}: counter of failedxcrun metalinvocations.metal_migration_count{from, to}: cross-node command transfers.
Agents can query these metrics to adjust their generation strategy. For example, if compilation failures spike, the agent might reduce code complexity or switch to a simpler kernel template.
Experimental Results and Throughput Gains
The paper tests two scenarios:
Concentrated Demand (Four Agents, Four Nodes)
Each agent submits a burst of commands. Without scheduling, agents queue locally and wait. With Metal Sandbox:
- 1.68× throughput for workloads dominated by parallel compilation.
- 2.05× throughput for mixed workloads with frequent serial execution.
The gain comes from parallel commands spreading across nodes and serial commands migrating to idle slots instead of waiting behind local queues.
Sustained Load (Sixteen Static Traces)
Replaying recorded agent sessions with four sessions per node (versus one) yields an estimated 2.14× sustained throughput. Dynamic scheduling further reduces:
- Mean tool waiting time by 18.8%.
- Batch elapsed time by 22.3%.
These gains assume phase durations remain constant. In practice, remote execution may add network latency, but the paper’s controlled LAN setup (1 Gbps Ethernet) keeps migration overhead below 200 ms for typical workspaces.
Failure Modes and Mitigation
| Failure | Impact | Mitigation |
|---|---|---|
| GPU hang during kernel execution | Serial slot blocked until watchdog timeout | Per-command timeout (default 30s), node marked degraded |
| Compilation crash (invalid Metal syntax) | Command fails, agent retries | Sandbox isolation prevents host crash, logs captured for debugging |
| Network partition during migration | Command lost, agent sees timeout | Resubmit to local queue, mark remote node unavailable |
| Workspace snapshot corruption | Execution fails with missing files | Checksum validation before migration, retry with fresh snapshot |
The scheduler does not attempt distributed consensus. If a node becomes unreachable, commands in flight are resubmitted. Agents tolerate retries because kernel generation is idempotent (same input code produces same compiled artifact).
Code Snippet: Submitting a Serial Command with Migration
import requests
import time
def execute_kernel(agent_id, workspace, kernel_path):
payload = {
"agent_id": agent_id,
"command": f"./run_kernel {kernel_path}",
"type": "serial",
"workspace": workspace,
"timeout": 30
}
resp = requests.post("http://scheduler:8080/submit", json=payload)
handle = resp.json()["handle"]
while True:
status = requests.get(f"http://scheduler:8080/status/{handle}").json()
if status["state"] == "completed":
return status["exit_code"], status["stdout"]
elif status["state"] == "failed":
raise RuntimeError(status["error"])
time.sleep(0.5)
The agent does not know or care whether the command ran locally or migrated. The scheduler handles placement transparently.
Deployment Shape
A typical setup:
- 4 to 8 Mac mini M4 nodes on a local network.
- One Harbor instance (can run on any node or a separate orchestrator).
- One scheduler process per node (reports to Harbor, accepts remote execution requests).
- Shared NFS or object storage for large datasets (optional, not required for workspace snapshots).
Each node runs macOS with Metal developer tools installed. The scheduler is a Go binary that uses os/exec for command execution and net/http for RPC. Harbor is a Python service with a SQLite database for rollout tracking.
For cloud deployments, replace Mac minis with EC2 Mac instances. Network latency increases migration cost, so tune the eligibility threshold or disable migration for latency-sensitive workloads.
Security Boundaries
- Sandbox profiles prevent agents from reading
/etc/passwdor writing to system directories. - No sudo or root access for agent commands.
- Network isolation: agents cannot open outbound connections (optional policy).
- Workspace encryption at rest (optional, via FileVault or APFS encryption).
The scheduler does not authenticate agents. In a multi-tenant environment, add API keys or mTLS between agents and Harbor.
Technical Verdict
Use Metal Sandbox when:
- You train or evaluate models that generate Apple Metal kernels and need high iteration velocity.
- You have multiple Mac nodes and want to amortize GPU idle time across concurrent agent sessions.
- You need isolation to prevent one agent’s bad kernel from crashing the host or corrupting shared state.
- You can tolerate 100-200 ms migration overhead for commands that would otherwise wait seconds in a local queue.
Avoid it when:
- You have a single Mac and no network of nodes (the overhead of workspace snapshotting and RPC outweighs the benefit).
- Your workload is purely inference (no compilation or execution), so GPU contention is not a bottleneck.
- You need sub-millisecond command latency (migration and scheduling add observable overhead).
- Your kernels require exclusive GPU access for minutes at a time (migration cannot help if no node ever becomes idle).
The infrastructure is open source and integrates cleanly with existing agent frameworks. If you are building GPU code generation agents on Apple Silicon, Metal Sandbox solves the resource contention problem without requiring a rewrite of your agent loop.