Skip to content

perf: Eliminate redundant syscalls in FSCache fetch and exists#11985

Merged
anthonyshew merged 1 commit intomainfrom
shew/fs-cache-fetch-optimization
Feb 24, 2026
Merged

perf: Eliminate redundant syscalls in FSCache fetch and exists#11985
anthonyshew merged 1 commit intomainfrom
shew/fs-cache-fetch-optimization

Conversation

@anthonyshew
Copy link
Copy Markdown
Contributor

@anthonyshew anthonyshew commented Feb 24, 2026

Summary

  • In fetch(), replace the exists() + CacheReader::open() two-step with a single open() attempt — 1 syscall instead of 3 on cache hits
  • Remove the legacy uncompressed .tar fallback from both fetch() and exists()put() has written .tar.zst exclusively since the Go-to-Rust port in mid-2023
  • Cache misses drop from 2 syscalls to 1
Repo Size Baseline (mean) Improved (mean) Change
~1,000 packages 1.536s ± 0.130s 1.439s ± 0.037s 97ms faster (6.3%), 71% less variance
~125 packages 615.6ms ± 136.7ms 558.5ms ± 23.3ms 57ms faster (9.3%), 83% less variance
5 packages 72.1ms ± 21.9ms 82.3ms ± 36.4ms noise (min times identical at ~55ms)

Profile data for the large repo shows fetch self-time dropped from 200.5ms (11.8%) to 129.6ms (8.0%) — a 35% reduction across 962 calls.

Benchmarks run on a Linux sandbox with hyperfine (15 runs, 2 warmup), all cache-hit scenarios.

Why

Every fetch() call was doing: stat(.tar) → ENOENT → stat(.tar.zst) → OK → open(.tar.zst) — 3 syscalls. The new flow is open(.tar.zst) → done. The uncompressed .tar path was a fallback for artifacts from the Go era (~2021-2022). No modern Turborepo version writes uncompressed cache artifacts, and cache entries rotate out constantly.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Feb 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
examples-basic-web Ready Ready Preview, Comment, Open in v0 Feb 24, 2026 5:55pm
examples-designsystem-docs Ready Ready Preview, Comment, Open in v0 Feb 24, 2026 5:55pm
examples-gatsby-web Ready Ready Preview, Comment, Open in v0 Feb 24, 2026 5:55pm
examples-kitchensink-blog Ready Ready Preview, Comment, Open in v0 Feb 24, 2026 5:55pm
examples-nonmonorepo Ready Ready Preview, Comment, Open in v0 Feb 24, 2026 5:55pm
examples-svelte-web Ready Ready Preview, Comment, Open in v0 Feb 24, 2026 5:55pm
examples-tailwind-web Ready Ready Preview, Comment, Open in v0 Feb 24, 2026 5:55pm
examples-vite-web Ready Ready Preview, Comment, Open in v0 Feb 24, 2026 5:55pm
turbo-site Ready Ready Preview, Comment, Open in v0 Feb 24, 2026 5:55pm
turborepo-agents Ready Ready Preview, Comment, Open in v0 Feb 24, 2026 5:55pm
turborepo-test-coverage Ready Ready Preview, Comment, Open in v0 Feb 24, 2026 5:55pm

In fetch(), replace the exists() + open() two-step with a single
open() attempt. Drop the legacy uncompressed .tar fallback — put()
has written .tar.zst exclusively since the Go-to-Rust port in 2023.

In exists(), check only .tar.zst.

This reduces cache hits from 3 syscalls to 1, and cache misses
from 2 syscalls to 1.
@github-actions
Copy link
Copy Markdown
Contributor

Coverage Report

Metric Coverage
Lines 75.10%
Functions 46.83%
Branches 0.00%

View full report

@anthonyshew anthonyshew enabled auto-merge (squash) February 24, 2026 18:17
@anthonyshew anthonyshew merged commit ba1e3bb into main Feb 24, 2026
172 of 178 checks passed
@anthonyshew anthonyshew deleted the shew/fs-cache-fetch-optimization branch February 24, 2026 18:25
anthonyshew added a commit that referenced this pull request Feb 25, 2026
## Release v2.8.11-canary.28

> [!NOTE]
> This release PR was created manually because the [automated release
workflow
failed](https://github.com/vercel/turborepo/actions/runs/22396672874/job/64834751381)
during the "Create Release PR" step. The npm packages were already
published successfully.

### Changes

- release(turborepo): 2.8.11-canary.27 (#11975) (`09e2557`)
- chore: Move git hooks from pre-commit to pre-push and match CI lint
checks (#11977) (`68928c0`)
- chore: Update AGENTS.md (#11978) (`3887e0d`)
- fix: Use correct pnpm version in library release workflow (#11979)
(`716229d`)
- fix: Fix library release workflow for Trusted Publishing OIDC (#11980)
(`f2b57af`)
- fix: Use repo setup-node action in library release package job
(#11981) (`c8d6fd8`)
- fix: Add repository field to @turbo/repository package.json (#11982)
(`2865110`)
- perf: Replace heap-allocated String with stack-allocated OidHash for
git OIDs (#11984) (`24e1937`)
- perf: Eliminate redundant syscalls in FSCache fetch and exists
(#11985) (`ba1e3bb`)
- release(library): 0.0.1-canary.19 (#11983) (`a5bc714`)
- perf: Reduce per-task allocations in visitor dispatch loop (#11986)
(`53b2b4f`)
- docs: Fix same-page anchor links that don't scroll to target (#11989)
(`b1d5ec2`)
- docs: Mention inputs key in package hash inputs table (#11990)
(`6bc216b`)
- fix(docs): update sitemap.md to single-line pipe-delimited format
(#11976) (`fd15d24`)
- fix: Disable husky pre-push hook during release staging (#11991)
(`2365307`)
- fix: Disable husky pre-push hook in release workflow (#11992)
(`71ca25c`)
github-actions Bot added a commit that referenced this pull request Feb 25, 2026
## Release v2.8.11-canary.29

Versioned docs: https://v2-8-11-canary-29.turborepo.dev

### Changes

- release(turborepo): 2.8.11-canary.27 (#11975) (`09e2557`)
- chore: Move git hooks from pre-commit to pre-push and match CI lint
checks (#11977) (`68928c0`)
- chore: Update AGENTS.md (#11978) (`3887e0d`)
- fix: Use correct pnpm version in library release workflow (#11979)
(`716229d`)
- fix: Fix library release workflow for Trusted Publishing OIDC (#11980)
(`f2b57af`)
- fix: Use repo setup-node action in library release package job
(#11981) (`c8d6fd8`)
- fix: Add repository field to @turbo/repository package.json (#11982)
(`2865110`)
- perf: Replace heap-allocated String with stack-allocated OidHash for
git OIDs (#11984) (`24e1937`)
- perf: Eliminate redundant syscalls in FSCache fetch and exists
(#11985) (`ba1e3bb`)
- release(library): 0.0.1-canary.19 (#11983) (`a5bc714`)
- perf: Reduce per-task allocations in visitor dispatch loop (#11986)
(`53b2b4f`)
- docs: Fix same-page anchor links that don't scroll to target (#11989)
(`b1d5ec2`)
- docs: Mention inputs key in package hash inputs table (#11990)
(`6bc216b`)
- fix(docs): update sitemap.md to single-line pipe-delimited format
(#11976) (`fd15d24`)
- fix: Disable husky pre-push hook during release staging (#11991)
(`2365307`)
- fix: Disable husky pre-push hook in release workflow (#11992)
(`71ca25c`)
- release(turborepo): 2.8.11-canary.28 (#11993) (`5793b0a`)
- fix: Use versioned schema URLs in Turborepo skill files (#11994)
(`7e48e24`)

---------

Co-authored-by: Turbobot <turbobot@vercel.com>
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.

1 participant