Skip to content

lint: cap -j=4 and use --allow-parallel-runners#5334

Merged
pietern merged 1 commit into
mainfrom
golangci-lint-faster
May 27, 2026
Merged

lint: cap -j=4 and use --allow-parallel-runners#5334
pietern merged 1 commit into
mainfrom
golangci-lint-faster

Conversation

@pietern
Copy link
Copy Markdown
Contributor

@pietern pietern commented May 27, 2026

Two changes to the four golangci-lint run invocations in Taskfile.yml:

./task lint, fresh caches, same tools/go.mod:

Cold wall Cold CPU (user+sys) Warm wall
origin/main 185s 2282s 4.1s
this PR 76s 327s 4.0s

2.4× faster cold wall, 7× less CPU. Warm runs are cache-bound and unchanged.

-j=4

golangci-lint scales poorly past 4–6 workers (upstream #5149). With three sub-lints running in parallel under lint-go, the default -j=GOMAXPROCS puts ~48 nominal workers on 16 cores — most of the 2282s on origin/main is kernel scheduling contention. Capping at 4 lets the three modules cooperate.

--allow-parallel-runners

By default golangci-lint takes a system-wide lock and refuses to start if another copy is already running. The per-task TMPDIR override existed to give each invocation its own copy of that lock file so it didn't collide; --allow-parallel-runners tells golangci-lint not to take the lock in the first place. Same outcome, no TMPDIR plumbing.

Parallel runs happen when lint-go fans out to the three module sub-lints, and when multiple worktrees lint at once.

Safe to skip the lock because golangci-lint v2.12.0 added content-addressable cache keys (PR #6445). Before that, two worktrees produced separate cache entries (keyed by absolute path) — no sharing, but also no contention. Now the entries are shared by content, so concurrent runs read and write the same files; the cache uses OS-level file locks with atomic write semantics to keep that safe. origin/main already pins v2.12.2.

Trade-off

Two task lint runs in the same worktree no longer fail-fast with "parallel golangci-lint is running" — they race instead, harmlessly but wastefully (duplicate analysis work). Minor.

Test plan

  • task lint clean
  • task lint-q clean
  • Parallel task lint across two worktrees both succeed
  • CI lint job passes

This pull request and its description were written by Isaac.

Add -j=4 and --allow-parallel-runners to the four golangci-lint
invocations in Taskfile.yml, and drop the per-task TMPDIR override
introduced in #5050. The TMPDIR override existed to give each
concurrent invocation its own copy of $TMPDIR/golangci-lint.lock;
--allow-parallel-runners tells golangci-lint not to acquire that
lock in the first place. Safe to do because golangci-lint v2.12.0
(already pinned on main) added content-addressable cache keys.
Cold `task lint` drops from ~185s to ~76s; warm runs are
cache-bound and unchanged.

Co-authored-by: Isaac
@pietern pietern temporarily deployed to test-trigger-is May 27, 2026 08:07 — with GitHub Actions Inactive
@pietern pietern temporarily deployed to test-trigger-is May 27, 2026 08:07 — with GitHub Actions Inactive
@pietern pietern requested review from denik and simonfaltum May 27, 2026 08:09
Copy link
Copy Markdown
Member

@simonfaltum simonfaltum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@eng-dev-ecosystem-bot
Copy link
Copy Markdown
Collaborator

Commit: a0a9b8b

Run: 26499047887

@pietern pietern merged commit d51cc3d into main May 27, 2026
29 of 30 checks passed
@pietern pietern deleted the golangci-lint-faster branch May 27, 2026 09:27
@eng-dev-ecosystem-bot
Copy link
Copy Markdown
Collaborator

Commit: d51cc3d

Run: 26502887867

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants