Skip to content

Decouple Download and Install Steps #4105

Open

Description

@Trenly

Description of the new feature / enhancement

Packages with package dependencies are now being accepted in the community repository. Running through the installation flow when dependencies are present results in the behavior Download package => Install package => Download package => Install package => . . . . This can be quite slow when there are multiple dependencies, the installer files are large, or it takes a significant amount of time to install a package.

While it is not a good idea to run multiple installs at the same time, it should be feasible to download the next installer while the previous installer is performing the install. In this way, it could be possible that the next installer would be fully downloaded before the previous installer has completed, reducing the overall time to install.

Download #1
||
||===================||
Install #1     Download #2
||                   ||
========||===========||
        ||           ||
    Install #2    Download #3
        ||           ||
        ======||=======
              ||
          Install #3

Proposed technical implementation details

Take the dependency tree and split it into separate download and install trees. Progress through the download tree consecutively without blocking. Once a node has been marked as completed in the download tree, process it in the install tree, queuing the installs until the previous install has completed.

Activity

  1. Trenly commented on Jan 26, 2024

    @Trenly
    ContributorAuthor

    After getting some sleep and thinking through this more - This could also benefit the upgrade --all, import, and multi-query install flows too

    [Policy] Command-Install
    [Policy] Command-Upgrade
    [Policy] Command-Import
    [Policy] Area-Performance

  2. added this to the milestone on Jan 26, 2024
  3. Trenly commented on Jan 29, 2024

    @Trenly
    ContributorAuthor

    Demitrius Nelon (@denelon) - looks like there isn’t a trigger for Area-Performance. I'll have to add one later. Would you mind adding the label manually?

  4. denelon commented on Jan 29, 2024

    @denelon
    Collaborator

    Area-Performance Issue related to CPU or memory performance looks like it was already there.

  5. removed this from the milestone on Nov 14, 2024
  6. nilspep commented on Sep 30, 2026

    @nilspep
    Contributor

    I've implemented this and measured it: downloading the next installers while the current package installs cuts multi-package operations by 20–34%, with no change to how or in what order packages are installed. I'd like to contribute it.

    Results

    About 600 runs on Azure VMs (x64 Release builds), each variant compared only against runs on the same VM. Median time for one winget install <packages>:

    Packages Link Today Download ahead Saved
    8 mixed (706 MB) 20 Mbit/s 507 s 335 s −34% (almost 3 min)
    8 mixed (706 MB) 100 Mbit/s 287 s 212 s −26%
    10 small (111 MB) 20 Mbit/s 83 s 57 s −31%
    10 small (111 MB) 100 Mbit/s 47 s 33 s −29%
    3 large (966 MB) 20 Mbit/s 581 s 465 s −20% (2 min)
    3 large (966 MB) 100 Mbit/s 225 s 171 s −24%
    12 real packages, publishers' CDNs Internet 270 s 216 s −20%

    The "Download ahead" column was measured with one download at a time and unbounded look-ahead; the final design with at most three installers ahead was within 2% of it in a separate series on the same VMs. The gain scales with download time: the slower the link, the more is saved. It is smallest when installation dominates (−5% for three large packages at 1 Gbit/s). With the feature off, timings match today's flow (±2%).

    Design

    • Experimental feature downloadAhead, off by default. With it off, the flow is unchanged.
    • Implemented in ProcessMultiplePackages, so install with several packages, upgrade --all and import all benefit.
    • Installs stay strictly serial and in the requested order. While a package installs, one background thread downloads the next installers: one download at a time, at most three installers ahead. Downloads pause while the dependencies of the current package are processed.
    • Every installer still goes through the normal download step before it is installed, which revalidates presence and hash; a missing or modified file is downloaded again. A failed download affects only its own package.
    • Microsoft Store, MSIX, authenticated downloads, --ignore-security-hash, download-only operations and duplicate packages in one list keep the normal flow.
    • Ctrl+C or early termination cancels the pending download, also while an installer is running. Through the COM API, cancellation reaches the background download once the running installation returns.

    This is in line with the feedback in #6295: I first built concurrent downloads (limits 1, 2, 4 and 8) and measured them. More concurrent downloads were never faster than one at a time; they split the bandwidth, delayed the next installation and kept up to 921 MB of installers on disk. A single look-ahead download left the link idle during long installations and was up to 19% slower. One download at a time with three installers ahead matched unbounded look-ahead within 2% in every scenario while bounding disk usage.

    Validation

    • 12 unit tests for order, the look-ahead limit, the pause for dependencies, cancellation, failure isolation, cache revalidation and hash checks. They do not depend on timing and were checked to fail when the limit or these rules are broken.
    • x64 and x86 Release builds with the full native unit test suites.
    • Two E2E tests that install an EXE and an MSI package in one command, with the feature on and off; the "on" test fails without the change.
    • The thread-safe FileLogger it relies on is already merged (Make FileLogger thread-safe #6571).

    Next steps

    A spec following doc/specs/spec-template.md and the implementation are ready. I plan to open the spec PR first and the implementation PR once the spec is agreed. If you'd rather fold this into the parallel installation spec in #6295, I'll adapt it. Raw data and benchmark scripts are available on request.

    Designed by me; GitHub Copilot assisted with implementation, testing and validation under my direction.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-PerformanceIssue related to CPU or memory performanceCommand-ImportIssue related to WinGet ImportCommand-InstallIssue related to WinGet InstallCommand-UpgradeIssue related to WinGet UpgradeIssue-FeatureThis is a feature request for the Windows Package Manager client.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions