Skip to content
Latchkey

GitLab Runner Concurrency Limits - config.toml concurrent / limit

How many jobs a runner host runs in parallel is governed by concurrent (global) and per-runner limit in config.toml. Set too low, jobs queue; set too high, the host is overloaded.

What this error means

Jobs sit in pending even though the runner is online and not busy, or the host is overwhelmed running too many jobs at once. The bottleneck is the concurrency configuration, not job tags.

config.toml
# config.toml - global cap is 1, so only one job runs at a time:
concurrent = 1

[[runners]]
  name = "docker-runner"
  limit = 0   # 0 = unlimited for this runner, but global concurrent still caps it

Common causes

Global concurrent set too low

The top-level concurrent value caps total simultaneous jobs across all runners on the host. A default of 1 serializes everything regardless of per-runner limits.

Per-runner limit too low

Each [[runners]] entry has a limit. A low value throttles that runner even when global concurrent allows more.

Concurrency set above host capacity

Too-high values let more jobs start than the CPU/memory can handle, causing thrashing, OOM kills, and slow jobs.

How to fix it

Tune global and per-runner concurrency

Set concurrent to the total parallel jobs the host can handle and limit per runner accordingly.

config.toml
concurrent = 8

[[runners]]
  name = "docker-runner"
  limit = 8
  [runners.docker]
    # ...

Right-size to host resources

  1. Estimate per-job CPU/memory and divide host capacity to pick a safe concurrent.
  2. Restart the runner after editing config.toml so changes take effect.
  3. Watch host load; lower the value if you see OOM kills or thrashing.

How to prevent it

  • Size concurrent from real per-job resource usage, not guesswork.
  • Keep per-runner limit consistent with global concurrent.
  • Monitor host CPU/memory and adjust concurrency to avoid overload.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →