Skip to content

Setup & Sizing

Sizing a Jenkins controller is less about total resources and more about how many concurrent things it’s promising to schedule at once.

  • Small (a handful of developers, a few pipelines running at once). Controller: 1-2 vCPU / 2-4Gi memory request, 2-4 executors. A modest persistent volume (10-20Gi) is enough if build history is actually bounded.
  • Medium (a team or two, steady pipeline traffic, several concurrent builds). Controller: 2-4 vCPU / 4-8Gi memory request, 6-10 executors — usually split across a couple of agent pod templates rather than one large generic agent. 50-100Gi volume, still bounded by retention policy.
  • Large (many teams, high concurrency, agents scaling frequently). Controller resourcing matters less at this point than agent pod template tuning — the controller becomes I/O- and scheduling-bound rather than CPU-bound. Favor more, smaller agent pods over fewer large ones, and watch JVM heap on the controller directly rather than guessing from tier.

A representative values.yaml shape at the medium tier — illustrative of the settings that matter, not copy-paste-ready for any specific cluster:

controller:
resources:
requests:
cpu: "2"
memory: "4Gi"
limits:
memory: "6Gi" # cap memory; leave CPU unbounded to avoid throttling under burst
javaOpts: "-Xmx3g -Xms3g" # heap sized under the memory limit, not up against it
numExecutors: 0 # keep the controller itself off the build queue
agent:
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
memory: "2Gi"
persistence:
size: 100Gi

Two settings matter regardless of tier: cap controller memory below the node’s actual limit (an OOM-killed controller loses in-flight state, not just a build), and keep numExecutors: 0 on the controller so build load lands on agents, not on the process also serving the UI and API.

Doubling controller resources treats a symptom, not a cause, if the real problem is unbounded growth or an agent lifecycle that isn’t actually disposable — check those first.

Related