RubyGems 3.4.17 skips remote lookup for a matching local gem
A resolver change avoids querying remote metadata for a locally supplied target while retaining remote resolution of its dependencies.
Installing a local gem does not necessarily mean every dependency is local. A private archive may depend on a public package, so the installer needs a way to use the supplied target without discarding remote sources for everything else. RubyGems 3.4.17 makes that distinction in its candidate lookup.
The July 14 release notes describe avoiding unnecessary work for private local gem installation. The linked pull request 6810 shows the specific change and a regression test. A matching local candidate now prevents a remote lookup for the same requirement.
I find Ruby's straightforward code useful for understanding maintenance changes of this size. The release note is brief, but the condition in the resolver and the test together explain exactly which request should disappear.
Candidate lookup previously considered both sources
The patch changes Gem::Resolver::InstallerSet#find_all. The method collects matching specifications from several places, including installed gems and local candidates. Before this change, it could also query the remote set whenever remote lookup was enabled.
That behavior did not distinguish a requirement already matched by the locally supplied archive. A private gem absent from the public source could still cause a remote metadata request for its name.
The new condition asks whether remote lookup is enabled and whether the matching-local collection is empty. Only when both are true does it append remote candidates. The collection starts empty, so the condition also has a defined value when local lookup is not being considered.
This is a change in where candidate information comes from. It does not replace the resolver or alter the dependencies declared inside the local archive. The relevant question is whether the current requirement has a matching local candidate.
The test preserves remote dependency installation
The regression test constructs two gems. Gem b is a local target with a dependency on gem a. The remote fixture can serve a, but the private local b is not present there.
The test makes any metadata lookup for b fail deliberately. It then installs the b archive and checks that both a and b have been installed. A passing result proves two properties within that fixture: no remote lookup for the local target, and continued remote installation of the dependency.
Those properties explain why an offline-only option would be a different behavior. The desired installation still needs a remote package. Turning off all networking would solve the unwanted target lookup by also disabling a capability the test requires.
The patch instead narrows remote lookup per requirement. When the resolver handles a and finds no matching local candidate, remote resolution remains available. When it handles the locally supplied b archive, the existing local match is sufficient for candidate collection.
A private target need not appear in the public index
The test explicitly models a compact index being available. Its failure condition is the attempt to request the private target's metadata from that source. General availability of the source is therefore not the problem being corrected.
A local archive carries its own identity and dependency declaration. Looking for that same private target in an unrelated remote index adds work without supplying the needed local artifact. The changed condition makes the provided candidate meaningful earlier in lookup.
The release labels this a performance improvement but provides no general timing result. The source supports a concrete reduction in work, one avoided category of remote metadata lookup when a matching local gem exists. Network conditions and dependency graphs determine how that affects a complete installation.
That specificity is the part I value. It connects an optimization to a request the installer should not need, rather than assuming that every patch release makes all installs faster.
The change remains conditional
The patch does not suppress remote lookup merely because some local gem exists. It filters local candidates using the current requirement. A local specification that does not match does not make the matching-local collection nonempty.
That preserves the distinction between the presence of an archive and satisfaction of a requirement. Remote lookup remains part of candidate discovery when the relevant local set supplies no match.
Likewise, the regression test is not evidence that every installation from a local archive is network-free. It intentionally downloads the dependency. A maintainer reading the result should retain that distinction when deciding whether an installation can run without remote access.
The release also updates bundled tooling
RubyGems 3.4.17 installs Bundler 2.4.17 as a default gem. The installation optimization itself is in RubyGems' resolver code, so the bundled Bundler version should not be mistaken for the location of the change.
The release provides the standard system-update command. Its documented effect is to update the RubyGems installation.
gem update --system
For the local-gem case, the useful behavior is more precise than a general speed claim. A matching local candidate satisfies target lookup without an unnecessary remote request, while dependencies absent locally can still be resolved and fetched from the configured remote source.