Skip to content

Run a parallel pre-check before updating toolchains#4752

Draft
FranciscoTGouveia wants to merge 1 commit intorust-lang:mainfrom
FranciscoTGouveia:update-performance
Draft

Run a parallel pre-check before updating toolchains#4752
FranciscoTGouveia wants to merge 1 commit intorust-lang:mainfrom
FranciscoTGouveia:update-performance

Conversation

@FranciscoTGouveia
Copy link
Contributor

Fixes #4747.

Instead of sequentially checking each toolchain for updates, rustup update now first checks all toolchains concurrently and only then performs the updates (if needed).

This brings two advantages:

  1. A no-op rustup update is now ~2x faster (see below);
  2. After updating a toolchain, there is no need to wait for the remaining toolchains to be checked for updates; this is especially helpful in cases where only nightly needs updating.

Benchmarks were run using hyperfine (20 iterations on a 50 Mbps connection) on a setup with 11 toolchains, and no regressions were observed.
For the no-op rustup update, this patch was 2.2x faster; for cases where a single toolchain was updated, there was no measurable difference.

CC @epage

@FranciscoTGouveia FranciscoTGouveia requested review from djc and rami3l March 15, 2026 20:40
Comment on lines +224 to +229
future::join_all(channels.iter().map(|(_, d)| d.show_dist_version()))
.await
.into_iter()
.map(|v| v.map_or(true, |opt| opt.is_some()))
.collect()
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there a cleaner way to achieve this?

Copy link
Member

@rami3l rami3l Mar 15, 2026

Choose a reason for hiding this comment

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

Am I reading it right that now for every toolchain that needs to be updated, the update is checked twice?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I forgot to add a comment about this, sorry.

I see two possible ways to proceed:

  1. Accept the cost of performing a double check. In practice, since the first check is done concurrently in a batch, the overhead should be relatively small.
  2. Do a small refactor, starting in DistOptions::install_into(), to allow skipping the second check.

Copy link
Member

Choose a reason for hiding this comment

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

@FranciscoTGouveia I think we should try to avoid double checking if the changes involved are not super disruptive 🙏

Comment on lines +219 to +220
// Run a pre-check to determine which channels have updates available.
// This step is skipped when force-updating.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Feedback on the wording of the comment is welcome :)

join_all(channels.iter().map(|(_, d)| d.show_dist_version()))
.await
.into_iter()
.map(|v| v.map_or(true, |opt| opt.is_some()))
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused by this logic. show_dist_version() seems to merely yield the latest available version, but that a DistributableToolchain has a manifest with a rust component with a version is_some() doesn't mean that it's newer than the installed version?

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.

Improve rustup updates performance by starting with a parallel check

3 participants