skip to content

What does Gradle's --max-workers flag (or org.gradle.workers.max property) control, and what is its default value?

level: juniorimportance: must knowfreq 55%

answer

  1. global concurrency ceiling
  2. shared by parallel tasks, test forks, Worker API
  3. default = available processors
  4. org.gradle.workers.max / --max-workers
  5. ceiling not target

basics

~10 s

It caps the maximum number of work items Gradle runs concurrently across the whole build — parallel tasks, test forks, Worker API jobs. It defaults to the number of CPU processors Gradle detects.

solid answer

~40 s

`--max-workers` (or `org.gradle.workers.max` in `gradle.properties`) sets the upper bound on how many units of work Gradle executes at once across the *entire* build. That global budget is shared by every concurrency mechanism: parallel project/task execution, forked test JVMs (`maxParallelForks`), and Worker API work items. By default Gradle sets it to the number of available processors reported by the JVM (`Runtime.availableProcessors()`). You lower it to leave headroom for other processes (e.g. on CI, or a laptop where you still want a responsive IDE), or raise/lower it to tune throughput. It is a ceiling, not a target — Gradle won't exceed it, but won't manufacture work to hit it either.

code

properties · 5 lines
properties
# gradle.properties
org.gradle.workers.max=4

# overridden per run:
# ./gradlew build --max-workers=6

go deeper

for a junior

Know that it caps concurrency and defaults to CPU count; know both the flag and the property name.

for a middle

Explain that the budget is shared across parallel tasks, test forks, and Worker API, and that it's a ceiling not a target.

for a senior

Discuss tuning trade-offs (memory vs CPU bound), CI container core-detection gotchas, and interaction with maxParallelForks.

for a principal

Frame org-wide defaults: standardizing workers.max in shared gradle.properties / init scripts across teams and CI to get predictable resource use.

## What the worker budget is Gradle has a single, build-wide **worker lease** pool. Every concurrent unit of work must acquire a lease before it runs, and there are only `max-workers` leases. This is the master throttle for *all* concurrency in a build, no matter where it comes from: - **Parallel project execution** (`org.gradle.parallel=true`) — tasks from independent projects running at the same time. - **Test forks** — JVMs spawned by the `Test` task; `maxParallelForks` requests several, but each running fork still consumes a lease. - **Worker API** work items submitted via `WorkerExecutor` (the *authoring* side is a separate topic; what matters here is that those items draw from the same budget). ## The default If you set nothing, Gradle picks `max-workers = Runtime.getRuntime().availableProcessors()` — the processor count the JVM sees. On an 8-core machine that's 8. Note that in containers this can be wrong if the JVM doesn't honor cgroup limits, which is a classic CI gotcha: the JVM may report the host's core count, not the container's quota. ## How to set it ```properties # gradle.properties org.gradle.workers.max=4 ``` or per-invocation: ```bash ./gradlew build --max-workers=4 ``` The command-line flag overrides the property for that invocation. ## Why tune it - **Lower** it to leave CPU/RAM for other work (IDE, browser, sibling CI jobs sharing a runner), or when builds thrash memory. - It interacts with **memory**: more workers = more concurrent JVMs/heap, so the right number is often memory-bound, not CPU-bound. - Setting it to `1` effectively serializes the build — useful for reproducing ordering bugs or for memory-starved environments. ## What it is NOT It is a *ceiling*. Gradle never spawns busy-work to reach it. If your task graph has no parallelism available (e.g. a single linear chain, or `org.gradle.parallel` is off so cross-project work can't overlap), a high `max-workers` does nothing.

  • If I have a single linear chain of tasks, does raising --max-workers speed it up?
    No. There is no independent work to overlap, so the extra leases sit idle. max-workers only helps when the task graph actually has parallelizable work.
  • Does --max-workers require org.gradle.parallel=true?
    Not for all concurrency. Test forks and Worker API items run concurrently within a project even without parallel project execution. But parallel execution *across* projects does require org.gradle.parallel=true; max-workers then caps that cross-project concurrency.

Think of it as the number of checkout lanes open in a store: you can never have more shoppers checking out at once than lanes, but opening more lanes doesn't create shoppers.

saying these in an interview costs you the question

  • Saying max-workers is the same flag as org.gradle.parallel — they're distinct; one is a ceiling, the other enables cross-project overlap.
  • Claiming the default is a fixed number like 4 rather than the detected processor count.

context