Skip to content
Latchkey
Documentation menu

Limits and concurrency

Job duration limits, concurrency, architecture support, disk sizes, and custom runner configuration limits per plan.

The numbers#

LimitValue
Maximum job duration4 hours per runner; the machine is terminated at 4 hours even if the job is still running
Concurrent jobs20 busy runners per workspace by default (idle warm runners do not count); higher limits available
Operating systemUbuntu 24.04 LTS only (no Windows or macOS runners)
Architecturex86_64 (amd64) only; no arm64 host runners (arm images can be cross-built with docker buildx)
Disk100 GB (small, medium, large), 200 GB (xlarge), 100 to 500 GB for custom configurations
Custom runner configurationsLaunch: 2, Scale: 10, Enterprise: unlimited
RegionRunners run in AWS us-east-1

What to do when you hit one#

The numbers only matter on the day one of them bites. What to change on your side when that happens:

durationA job approaches 4 hoursThe machine terminates at 4 hours even mid-job, so treat the cap as a hard ceiling, not a budget. Split the work into parallel jobs (each gets its own runner), or move it up a size so the same work finishes sooner.
concurrencyJobs queue at busy momentsThe default is 20 busy runners per workspace, and idle warm runners never count against it. Jobs beyond the limit wait in the queue until a busy runner finishes; if your peaks queue regularly, higher limits are available.
platformYou need Windows, macOS, or arm64Keep those specific jobs on GitHub-hosted or other runners and mix freely within the same workflow. For arm64 container images, cross-build with docker buildx; QEMU is preconfigured on the image.
diskJobs fill the diskSelf-healing prunes caches when a disk fills mid-job, but if a job routinely needs more space than its size provides, the durable fix is a custom configuration with up to 500 GB.

Two of these deserve a why. The 4-hour cap is the same backstop that keeps self-healing retries from ever running up your bill: it guarantees that a hung job cannot hold a machine, or your invoice, indefinitely. And the concurrency limit counts busy runners only, which is easy to misread: a warm pool sitting idle costs you none of the 20 slots, so warm capacity never competes with your real jobs.

Custom runner configurations#

From the Latchkey Runners page, you can create custom configurations with their own latchkey-<name> labels, choosing CPU/memory shape and disk size. The AI Scan flow analyzes your workflows and proposes the right configuration; its image is then built automatically and you are notified when the runner is ready to use. Until the image build completes, jobs targeting that label wait in the queue.

The full decision guide, including when a custom shape beats a preset and what it costs, is in Custom runners with AI Scan.

Good to know#

  • Runners are single-use: one job per machine, destroyed afterward. Anything you write to local disk is gone when the job ends; use artifacts or caches for persistence.
  • GitHub-hosted runner labels (ubuntu-latest and friends) keep working side by side; you can migrate one job at a time.
  • If you need GPU, Windows, macOS, or arm64 hosts, keep those specific jobs on GitHub-hosted or other runners for now and mix freely within the same workflow.