Skip to content

Fix very slow remote temp root registration in copyPaths() - #538

Merged
edolstra merged 4 commits into
mainfrom
add-temp-roots
Jul 7, 2026
Merged

edolstra merged 4 commits into
mainfrom
add-temp-roots

Conversation

@edolstra

@edolstra edolstra commented Jul 7, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

Since 734a205, copyPaths() calls addTempRoot() on the remote store for every path in the closure. However, this is extremely show for large closures, especially over high-latency SSH connections. So now, we use a new daemon operation AddTempRoots to do all paths in a single call.

Fixes #533. This borrows the addTempRoots() interface added in NixOS#15719.

Context

Summary by CodeRabbit

  • New Features

    • Temporary GC roots can now be registered in batches (multiple paths at once), including when preparing builds and copying paths.
    • Remote daemon communication now supports a bulk “add temp roots” operation when available.
  • Bug Fixes

    • More efficient temporary-root registration by reducing per-path messaging and choosing the best supported protocol behavior for the target daemon.
    • Improved persistence and handling of temporary roots by recording multiple paths together, and acknowledging registrations consistently when GC is active.

dramforever and others added 2 commits July 7, 2026 11:01
Introduce LocalStore::addTempRoots, which adds all temproots in a batch
for LocalStore.

Make this available from the base class Store by making a virtual method
Store::addTempRoots, overriding it in LocalStore and RemoteStore (it is
just a loop for each path because the benefit of having this be batched
is unclear), and making the single-path Store::addTempRoot a wrapper
around that.
Since 734a205, copyPaths() calls
addTempRoot() on the remote store for every path in the
closure. However, this is extremely show for large closures,
especially over high-latency SSH connections. So now, we use a new
daemon operation AddTempRoots to do all paths in a single call.

Fixes #533.

Assisted-by: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2d26e3df-3ece-4c33-b88b-9e11a0d02686

📥 Commits

Reviewing files that changed from the base of the PR and between 7beda55 and 334f160.

📒 Files selected for processing (2)
  • src/libstore/build/derivation-goal.cc
  • src/nix/nix-store/nix-store.cc

📝 Walkthrough

Walkthrough

Temporary GC root registration now uses batched addTempRoots(StorePathSet) calls end-to-end, with a new worker protocol opcode/feature, daemon handling, RemoteStore fallback logic, and updated callers that no longer loop per path.

Changes

Batch addTempRoots API

Layer / File(s) Summary
Store base interface change
src/libstore/include/nix/store/store-api.hh, src/libstore/include/nix/store/gc-store.hh, src/libstore/include/nix/store/worker-protocol.hh, src/libstore/worker-protocol.cc
addTempRoot becomes a wrapper over new virtual addTempRoots(StorePathSet), and the worker protocol advertises featureAddTempRoots plus AddTempRoots = 49.
Daemon and LocalStore handling
src/libstore/daemon.cc, src/libstore/include/nix/store/local-store.hh, src/libstore/gc.cc
The daemon accepts AddTempRoots, LocalStore overrides the plural API, socket notifications iterate over each path, and temp-roots persistence writes one NUL-separated batch.
RemoteStore client-side batching
src/libstore/include/nix/store/remote-store.hh, src/libstore/remote-store.cc
RemoteStore switches to addTempRoots, uses the new feature when available, and falls back to per-path requests otherwise.
Caller updates
src/libstore/restricted-store.cc, src/libstore/store-api.cc, src/libstore/build/derivation-goal.cc, src/nix/nix-store/nix-store.cc
Call sites and overrides are updated to register temporary roots in bulk instead of looping over single-path calls.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: batching remote temp-root registration in copyPaths().
Linked Issues check ✅ Passed The changes implement batched temp-root registration and a new AddTempRoots protocol path, matching the fix requested in #533.
Out of Scope Changes check ✅ Passed The PR stays focused on temp-root batching and protocol support; no unrelated code changes are evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch add-temp-roots

Comment @coderabbitai help to get the list of available commands.

Use the new batched addTempRoots for both convenience and better
performance for LocalStore.
Use the new batched addTempRoots for both convenience and better
performance for LocalStore.
@github-actions

github-actions Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/libstore/include/nix/store/store-api.hh (1)

726-742: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Keep addTempRoot virtual for downstream stores.
addTempRoot(const StorePath&) is now a non-virtual wrapper, so any out-of-tree Store subclass that still overrides the old signature will compile but stop participating in GC when called through Store&/Store*. In-tree implementations already use addTempRoots, but this is still a breaking API change for public consumers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/libstore/include/nix/store/store-api.hh` around lines 726 - 742, Keep
addTempRoot(const StorePath&) virtual in Store so downstream Store subclasses
overriding the single-path API still participate in garbage collection when
called through Store& or Store*. Update the Store interface around addTempRoot
and addTempRoots so addTempRoot remains a virtual entry point (or otherwise
forwards in a way that preserves overrides), and keep the existing addTempRoots
behavior for bulk roots.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/libstore/include/nix/store/store-api.hh`:
- Around line 726-742: Keep addTempRoot(const StorePath&) virtual in Store so
downstream Store subclasses overriding the single-path API still participate in
garbage collection when called through Store& or Store*. Update the Store
interface around addTempRoot and addTempRoots so addTempRoot remains a virtual
entry point (or otherwise forwards in a way that preserves overrides), and keep
the existing addTempRoots behavior for bulk roots.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 863ba6be-aaa4-41e1-8777-f23e47e2a3b9

📥 Commits

Reviewing files that changed from the base of the PR and between 46e041f and 7beda55.

📒 Files selected for processing (11)
  • src/libstore/daemon.cc
  • src/libstore/gc.cc
  • src/libstore/include/nix/store/gc-store.hh
  • src/libstore/include/nix/store/local-store.hh
  • src/libstore/include/nix/store/remote-store.hh
  • src/libstore/include/nix/store/store-api.hh
  • src/libstore/include/nix/store/worker-protocol.hh
  • src/libstore/remote-store.cc
  • src/libstore/restricted-store.cc
  • src/libstore/store-api.cc
  • src/libstore/worker-protocol.cc

@github-actions
github-actions Bot temporarily deployed to pull request July 7, 2026 09:31 Inactive
@edolstra
edolstra added this pull request to the merge queue Jul 7, 2026
Merged via the queue into main with commit c8359e8 Jul 7, 2026
33 checks passed
@edolstra
edolstra deleted the add-temp-roots branch July 7, 2026 15:00

This branch was previously deployed

1 inactive deployment
pull request — 334f160a Deployed Jul 7, 2026 by github-actions[bot]
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.

ssh-ng client ~66× slower than upstream nix 2.34.7 for closure copies (per-path connection reopen)

3 participants