Skip to content

Use separate Bundler download and installation workers - #9777

Open
joshuay03 wants to merge 2 commits into
ruby:masterfrom
joshuay03:separate-download-jobs
Open

Use separate Bundler download and installation workers#9777
joshuay03 wants to merge 2 commits into
ruby:masterfrom
joshuay03:separate-download-jobs

Conversation

@joshuay03

@joshuay03 joshuay03 commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

What was the end-user or developer problem that led to this PR?

Bundler uses one worker pool for gem downloads and installations. A slow download occupies a slot that could install an already downloaded gem, while a slow native extension build occupies a slot that could download another gem.

What is your fix for the problem, implemented in this PR?

Use separate download and installation worker pools connected to a shared completion queue. Both pools retain the existing BUNDLE_JOBS size, and compact-index metadata concurrency remains unchanged. This lets network I/O overlap installation without changing Bundler's existing concurrency settings.

Serialize on-demand remote spec lookups so concurrent default-gem downloads cannot race while refreshing shared source state.

Scope update

Add BUNDLE_DOWNLOAD_JOBS and BUNDLE_METADATA_JOBS, and make BUNDLE_JOBS installation-only. Downloads default to 3× installation jobs, capped at 8; metadata defaults to download jobs.

Across five alternating cold-cache Docker builds per variant, median install time improved by 8.5% (66.0s versus 72.1s) and mean install time improved by 9.2% (67.2s versus 74.0s).

Those statements are outdated because the original benchmark changed both the scheduler and its concurrency settings. With concurrency matched to master, review measurements retained a 7.6% reduction from the original 9.5% reduction. My benchmark host reported nproc as 11, and I do not have a measurement that isolates the settings. This revision therefore keeps the scheduler and race fix while removing the new settings and the narrower BUNDLE_JOBS semantics.

Make sure the following tasks are checked

@joshuay03
joshuay03 force-pushed the separate-download-jobs branch 2 times, most recently from 58b24f1 to 1f928f3 Compare August 16, 2026 23:17
@joshuay03 joshuay03 changed the title Separate download and installation concurrency Separate Bundler installation and I/O concurrency Aug 16, 2026
@joshuay03
joshuay03 force-pushed the separate-download-jobs branch 3 times, most recently from 78245cf to 9da6fe0 Compare August 16, 2026 23:26
@joshuay03 joshuay03 changed the title Separate Bundler installation and I/O concurrency Separate Bundler install, download, and metadata concurrency Aug 16, 2026
@joshuay03 joshuay03 moved this to On Hold in Open Source Aug 16, 2026
@joshuay03 joshuay03 moved this from On Hold to In Progress / Pending Review in Open Source Aug 16, 2026
@joshuay03
joshuay03 force-pushed the separate-download-jobs branch 3 times, most recently from 71f2793 to 14daf5c Compare August 17, 2026 03:11
@joshuay03 joshuay03 changed the title Separate Bundler install, download, and metadata concurrency Separate Bundler installation, download, and metadata concurrency Aug 17, 2026
@joshuay03
joshuay03 force-pushed the separate-download-jobs branch 2 times, most recently from e35b8c0 to c5d6166 Compare August 17, 2026 03:17
@joshuay03 joshuay03 changed the title Separate Bundler installation, download, and metadata concurrency Separate Bundler download, installation, and metadata concurrency Aug 17, 2026
@joshuay03
joshuay03 force-pushed the separate-download-jobs branch 2 times, most recently from 5605a3a to 36d082b Compare August 17, 2026 04:14
@joshuay03
joshuay03 marked this pull request as ready for review August 17, 2026 04:42
@hsbt

hsbt commented Sep 3, 2026

Copy link
Copy Markdown
Member

I reproduced this locally and would like to narrow the scope before merging.

On a 10-core macOS arm64 box, cold cache, 94-gem lockfile: at the default settings the split is a wash, 28.57s median before vs 28.68s after (n=6, alternating). With BUNDLE_JOBS=2 I do get your number, -7.9%. But when I pin BUNDLE_DOWNLOAD_JOBS=2 and BUNDLE_METADATA_JOBS=10 on your branch so the concurrency matches master and only the scheduler differs, I still get -7.6% out of that -9.5%. Almost all of the win is the two-pool rewrite in parallel_installer.rb, not the new settings.

So I would like to take the scheduler change and the @remote_spec_for_mutex race fix, and drop BUNDLE_DOWNLOAD_JOBS, BUNDLE_METADATA_JOBS, and the BUNDLE_JOBS narrowing. Being fast out of the box is worth more to users than a knob most of them will never find, and the numbers say the scheduler rewrite already gets us there. The new defaults also lower download and metadata concurrency from processor_count to 8 on machines with 9 or more cores, so as they stand they add a setting and a regression at the same time.

Does that work for you, or do you have a measurement that isolates the settings from the scheduler change? What is nproc on your benchmark host?

@joshuay03

Copy link
Copy Markdown
Contributor Author

That works for me. nproc on my benchmark host was 11. I do not have a measurement that isolates the settings from the scheduler change. I will update the PR to address the feedback and narrow its scope as requested.

@joshuay03
joshuay03 force-pushed the separate-download-jobs branch from 36d082b to dcc81e7 Compare September 4, 2026 02:54
@joshuay03 joshuay03 changed the title Separate Bundler download, installation, and metadata concurrency Use separate Bundler download and installation workers Sep 4, 2026
@joshuay03
joshuay03 force-pushed the separate-download-jobs branch from dcc81e7 to 8c64620 Compare September 4, 2026 03:44

@hsbt hsbt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

👍 Thanks!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants