Skip to main content

Runner Pools

A runner pool is a named, capability-tagged group of runners that pulls jobs from Roboticks. Every test job carries a set of requirements — ROS distro, simulator, GPU, network posture — and the job_router dispatches it to the pool that fits. There are two pool types. Same wire contract, same job payload, different fulfillment.

Hosted pools

Roboticks operates them. ECS Fargate Spot for ROS2 CPU, EC2 G4dn Spot for Gazebo Harmonic, mixed for Webots. Billed per sim minute.

Self-hosted pools

You operate them via the roboticks-runner Go binary v2. Free of compute charges. Required for air-gapped.

Hosted pool catalog

PoolBackingTypical useIndicative price
hosted-ros2-cpuFargate Spot, 4 vCPU / 8 GBpytest, gtest, launch_testing on a ROS2 node graph~$0.02 / min
hosted-gazebo-gpuEC2 G4dn.xlarge Spot Fleet (NVIDIA T4)Gazebo Harmonic worlds, sensor simulation~$0.10 / min
hosted-webots-cpuFargate Spot, 8 vCPU / 16 GBWebots scenes without GPU shaders~$0.04 / min
hosted-webots-gpuEC2 G4dn.xlarge Spot FleetWebots with GPU rendering~$0.10 / min
Spot interruption is handled by the platform — interrupted jobs requeue automatically. See Pricing for the canonical rate card.

Self-hosted pool model

You declare a pool in the dashboard or via rbtk pool create, mint a registration token, then run rbtk-runner register on each machine that should join. The runner polls /internal/runners/poll, declares its capabilities (ROS distros installed, sim engines available, GPU model, max concurrent jobs), and heartbeats every 15 seconds with token rotation.

Routing rules

The job_router resolves each job against pool capabilities in this order:
  1. project.airgapped == true — only self-hosted pools in the project’s namespace are considered. Hosted pools are excluded even if they match capabilities.
  2. requires_sim + self-hosted GPU capacity available — prefer the self-hosted pool (free of compute).
  3. requires_sim + no self-hosted GPU capacity — fall back to a hosted GPU pool. Pre-MVP customers can require explicit opt-in via project.hosted_fallback = true.
  4. Plain ROS2 test (no simulator) — load-balance: try self-hosted first, then hosted. The router prefers warm runners over cold-start hosted Fargate tasks.
Capabilities are matched all-or-nothing: a job needing ros: humble and sim: gazebo-harmonic will skip a runner that only declares ros: iron.

How Roboticks differs from GitHub-Actions self-hosted runners

You may already know the GitHub self-hosted runner. roboticks-runner is purpose-built for the V&V loop:
GH Actions runnerroboticks-runner v2
Auth scopeRepo or org levelProject-scoped — one token per project pool
ROS2 preinstallNoneHumble / Iron / Rolling images bundled
Sim enginesNoneGazebo Harmonic and Webots preconfigured
MCAP captureCustom action requiredDirect presigned-URL upload to S3
TraceabilityNoneReads @confirms from pytest output, emits link rows
Network egressGitHub + arbitraryRoboticks platform only (air-gapped mode locks this in)
DistributionGitHub-tarball, opaqueCosign-signed, cross-platform GitHub Releases
UpdatesAuto, sometimes disruptiveDrain-then-replace; pinned versions supported

Why a pool, not just a runner

Pools let you declare policy at one level and let many machines fulfill it:
  • A single prod-gpu-farm pool can have 12 machines, each declaring its GPU model. The router fans out across all of them.
  • Quotas and concurrency caps live on the pool, not the runner.
  • Air-gapped, network-isolated, and license-restricted (e.g., LDRA-licensed-host) jobs share one routing primitive.

Next steps

Install a runner

Linux, macOS, Windows. Cross-arch binaries from GitHub Releases.

Create a pool

Dashboard or CLI. Registration tokens, rotation, revoking.

GPU setup

nvidia-container-toolkit, multi-GPU, capability declaration.

Air-gapped mode

On-prem only. Enterprise tier. No GitHub connectivity required.