Skip to content

Turbopack: Add TransientEnvMap to avoid persisting env vars in cache#90526

Open
sokra wants to merge 2 commits intocanaryfrom
sokra/env-in-cache
Open

Turbopack: Add TransientEnvMap to avoid persisting env vars in cache#90526
sokra wants to merge 2 commits intocanaryfrom
sokra/env-in-cache

Conversation

@sokra
Copy link
Member

@sokra sokra commented Feb 25, 2026

What?

Introduces a new TransientEnvMap type and changes ProcessEnv::read_all() to return Vc<TransientEnvMap> instead of Vc<EnvMap>.

Why?

EnvMap uses default (auto) serialization, which means all process environment variables — including secrets like API keys and tokens — could be written to the persistent disk cache. TransientEnvMap uses serialization = "none", ensuring env vars are never persisted and must always be read fresh from the process environment on cache restore.

How?

  • Added TransientEnvMap in turbo-tasks-env/src/lib.rs: a transparent wrapper around FxIndexMap<RcStr, RcStr> with serialization = "none"
  • Changed ProcessEnv::read_all() trait method return type from Vc<EnvMap>Vc<TransientEnvMap>
  • Updated all 7 implementations of ProcessEnv::read_all() (EnvMap, CommandLineProcessEnv, CustomProcessEnv, FilterProcessEnv, DotenvProcessEnv, TryDotenvProcessEnv, EmbeddableProcessEnv)
  • Updated helper functions (case_insensitive_read, to_uppercase_map, common_node_env) to work with TransientEnvMap
  • EnvMap (serializable) is kept for config-derived env maps like next.config.js env and edge_env

Introduces TransientEnvMap (serialization = "none") and changes
ProcessEnv::read_all() to return it instead of EnvMap. This prevents
environment variables (which may contain secrets) from being stored
in the persistent disk cache.

EnvMap (serializable) is kept for config-derived env maps such as
next.config.js env and edge_env.
@vercel
Copy link
Contributor

vercel bot commented Feb 25, 2026

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

Project Deployment Actions Updated (UTC)
next-js Error Error Feb 25, 2026 3:05pm

@nextjs-bot nextjs-bot added created-by: Turbopack team PRs by the Turbopack team. Turbopack Related to Turbopack with Next.js. labels Feb 25, 2026
@nextjs-bot
Copy link
Collaborator

nextjs-bot commented Feb 25, 2026

Failing test suites

Commit: 72255e1 | About building and testing Next.js

pnpm test-start-turbo test/e2e/app-dir/nx-handling/nx-handling.test.ts (turbopack) (job)

  • nx-handling > should work for pages page (DD)
  • nx-handling > should work for pages API (DD)
  • nx-handling > should work with app page (DD)
  • nx-handling > should work with app route (DD)
Expand output

● nx-handling › should work for pages page

next start exited unexpectedly with code/signal 130

  151 |               require('console').error(message)
  152 |             }
> 153 |             reject(new Error(message))
      |                    ^
  154 |           }
  155 |         })
  156 |

  at ChildProcess.<anonymous> (lib/next-modes/next-start.ts:153:20)

● nx-handling › should work for pages API

next start exited unexpectedly with code/signal 130

  151 |               require('console').error(message)
  152 |             }
> 153 |             reject(new Error(message))
      |                    ^
  154 |           }
  155 |         })
  156 |

  at ChildProcess.<anonymous> (lib/next-modes/next-start.ts:153:20)

● nx-handling › should work with app page

next start exited unexpectedly with code/signal 130

  151 |               require('console').error(message)
  152 |             }
> 153 |             reject(new Error(message))
      |                    ^
  154 |           }
  155 |         })
  156 |

  at ChildProcess.<anonymous> (lib/next-modes/next-start.ts:153:20)

● nx-handling › should work with app route

next start exited unexpectedly with code/signal 130

  151 |               require('console').error(message)
  152 |             }
> 153 |             reject(new Error(message))
      |                    ^
  154 |           }
  155 |         })
  156 |

  at ChildProcess.<anonymous> (lib/next-modes/next-start.ts:153:20)

pnpm test-start-turbo test/e2e/app-dir/segment-cache/revalidation/segment-cache-revalidation.test.ts (turbopack) (job)

  • layout sharing in non-static prefetches > full prefetches should omit layouts that were already prefetched with a full prefetch (DD)
Expand output

● layout sharing in non-static prefetches › full prefetches should omit layouts that were already prefetched with a full prefetch

thrown: "Exceeded timeout of 60000 ms for a test.
Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout."

  50 |       }
  51 |
> 52 |       const result = Reflect.apply(target, thisArg, args)
     |                              ^
  53 |       return typeof result === 'function' ? wrapJestTestFn(result) : result
  54 |     },
  55 |     get(target, prop, receiver) {

  at Object.apply (lib/e2e-utils/index.ts:52:30)
  at it (e2e/app-dir/segment-cache/prefetch-layout-sharing/prefetch-layout-sharing.test.ts:121:3)
  at Object.describe (e2e/app-dir/segment-cache/prefetch-layout-sharing/prefetch-layout-sharing.test.ts:6:1)

pnpm test-start test/e2e/app-dir/app-prefetch/prefetching.test.ts (job)

  • app dir - prefetching > should show layout eagerly when prefetched with loading one level down (DD)
  • app dir - prefetching > should immediately render the loading state for a dynamic segment when fetched from higher up in the tree (DD)
Expand output

● app dir - prefetching › should show layout eagerly when prefetched with loading one level down

thrown: "Exceeded timeout of 60000 ms for a test.
Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout."

  50 |       }
  51 |
> 52 |       const result = Reflect.apply(target, thisArg, args)
     |                              ^
  53 |       return typeof result === 'function' ? wrapJestTestFn(result) : result
  54 |     },
  55 |     get(target, prop, receiver) {

  at Object.apply (lib/e2e-utils/index.ts:52:30)
  at it (e2e/app-dir/app-prefetch/prefetching.test.ts:28:3)
  at Object.describe (e2e/app-dir/app-prefetch/prefetching.test.ts:11:1)

● app dir - prefetching › should immediately render the loading state for a dynamic segment when fetched from higher up in the tree

thrown: "Exceeded timeout of 60000 ms for a test.
Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout."

  50 |       }
  51 |
> 52 |       const result = Reflect.apply(target, thisArg, args)
     |                              ^
  53 |       return typeof result === 'function' ? wrapJestTestFn(result) : result
  54 |     },
  55 |     get(target, prop, receiver) {

  at Object.apply (lib/e2e-utils/index.ts:52:30)
  at it (e2e/app-dir/app-prefetch/prefetching.test.ts:304:3)
  at Object.describe (e2e/app-dir/app-prefetch/prefetching.test.ts:11:1)

pnpm test-start-turbo test/e2e/app-dir/app-client-cache/client-cache.parallel-routes.test.ts (turbopack) (job)

  • filesystem-caching with cache enabled > should cache or not cache loaders (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (RSC change) (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (RCC change) (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (Pages change) (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (rename app page) (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (next config change) (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (env var change) (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (RSC change, RCC change, Pages change, rename app page, next config change, env var change) (DD)
Expand output

● filesystem-caching with cache enabled › should cache or not cache loaders

expect(received).toBe(expected) // Object.is equality

Expected: "Timestamp = 1772033621972"
Received: "Timestamp = 1772033626640"

  145 |           expect(newTimestamp).toMatch(/Timestamp = \d+$/)
  146 |           if (cacheEnabled) {
> 147 |             expect(newTimestamp).toBe(appTimestamp)
      |                                  ^
  148 |           } else {
  149 |             expect(newTimestamp).not.toBe(appTimestamp)
  150 |           }

  at Object.toBe (e2e/filesystem-cache/filesystem-cache.test.ts:147:34)

● filesystem-caching with cache enabled › should allow to change files while stopped (RSC change)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033634476"
Received: "Timestamp = 1772033630529"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at NextStartInstance.patchFile (lib/next-modes/base.ts:742:9)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

● filesystem-caching with cache enabled › should allow to change files while stopped (RCC change)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033643154"
Received: "Timestamp = 1772033638808"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at NextStartInstance.patchFile (lib/next-modes/base.ts:742:9)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

● filesystem-caching with cache enabled › should allow to change files while stopped (Pages change)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033651160"
Received: "Timestamp = 1772033647210"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at NextStartInstance.patchFile (lib/next-modes/base.ts:742:9)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

● filesystem-caching with cache enabled › should allow to change files while stopped (rename app page)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033659798"
Received: "Timestamp = 1772033655462"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:251:13)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

● filesystem-caching with cache enabled › should allow to change files while stopped (next config change)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033669097"
Received: "Timestamp = 1772033664250"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at NextStartInstance.patchFile (lib/next-modes/base.ts:742:9)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

● filesystem-caching with cache enabled › should allow to change files while stopped (env var change)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033677969"
Received: "Timestamp = 1772033673545"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:296:13)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

● filesystem-caching with cache enabled › should allow to change files while stopped (RSC change, RCC change, Pages change, rename app page, next config change, env var change)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033687709"
Received: "Timestamp = 1772033682445"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at NextStartInstance.patchFile (lib/next-modes/base.ts:742:9)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at NextStartInstance.patchFile (lib/next-modes/base.ts:742:9)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at NextStartInstance.patchFile (lib/next-modes/base.ts:742:9)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:251:13)
  at NextStartInstance.patchFile (lib/next-modes/base.ts:742:9)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:296:13)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

pnpm test-dev-turbo test/e2e/filesystem-cache/filesystem-cache.test.ts (turbopack) (job)

  • filesystem-caching with cache enabled > should cache or not cache loaders (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (RSC change) (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (RCC change) (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (Pages change) (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (rename app page) (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (next config change) (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (env var change) (DD)
  • filesystem-caching with cache enabled > should allow to change files while stopped (RSC change, RCC change, Pages change, rename app page, next config change, env var change) (DD)
Expand output

● filesystem-caching with cache enabled › should cache or not cache loaders

expect(received).toBe(expected) // Object.is equality

Expected: "Timestamp = 1772033661835"
Received: "Timestamp = 1772033669488"

  145 |           expect(newTimestamp).toMatch(/Timestamp = \d+$/)
  146 |           if (cacheEnabled) {
> 147 |             expect(newTimestamp).toBe(appTimestamp)
      |                                  ^
  148 |           } else {
  149 |             expect(newTimestamp).not.toBe(appTimestamp)
  150 |           }

  at Object.toBe (e2e/filesystem-cache/filesystem-cache.test.ts:147:34)

● filesystem-caching with cache enabled › should allow to change files while stopped (RSC change)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033682016"
Received: "Timestamp = 1772033677303"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at NextDevInstance.patchFile (lib/next-modes/base.ts:742:9)
  at NextDevInstance.patchFile (lib/next-modes/next-dev.ts:304:16)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

● filesystem-caching with cache enabled › should allow to change files while stopped (RCC change)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033694453"
Received: "Timestamp = 1772033689727"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at NextDevInstance.patchFile (lib/next-modes/base.ts:742:9)
  at NextDevInstance.patchFile (lib/next-modes/next-dev.ts:304:16)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

● filesystem-caching with cache enabled › should allow to change files while stopped (Pages change)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033706836"
Received: "Timestamp = 1772033702106"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at NextDevInstance.patchFile (lib/next-modes/base.ts:742:9)
  at NextDevInstance.patchFile (lib/next-modes/next-dev.ts:304:16)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

● filesystem-caching with cache enabled › should allow to change files while stopped (rename app page)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033720244"
Received: "Timestamp = 1772033715082"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:251:13)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

● filesystem-caching with cache enabled › should allow to change files while stopped (next config change)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033733803"
Received: "Timestamp = 1772033728851"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at NextDevInstance.patchFile (lib/next-modes/base.ts:742:9)
  at NextDevInstance.patchFile (lib/next-modes/next-dev.ts:304:16)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

● filesystem-caching with cache enabled › should allow to change files while stopped (env var change)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033747299"
Received: "Timestamp = 1772033742369"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:296:13)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

● filesystem-caching with cache enabled › should allow to change files while stopped (RSC change, RCC change, Pages change, rename app page, next config change, env var change)

expect(received).toEqual(expected) // deep equality

Expected: "Timestamp = 1772033762974"
Received: "Timestamp = 1772033756624"

  349 |               const browser = await next.browser('/unchanged')
  350 |               const timestamp = await browser.elementByCss('main').text()
> 351 |               expect(unchangedTimestamp).toEqual(timestamp)
      |                                          ^
  352 |               await browser.close()
  353 |             }
  354 |           }

  at toEqual (e2e/filesystem-cache/filesystem-cache.test.ts:351:42)
  at inner (e2e/filesystem-cache/filesystem-cache.test.ts:361:13)
  at NextDevInstance.patchFile (lib/next-modes/base.ts:742:9)
  at NextDevInstance.patchFile (lib/next-modes/next-dev.ts:304:16)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at NextDevInstance.patchFile (lib/next-modes/base.ts:742:9)
  at NextDevInstance.patchFile (lib/next-modes/next-dev.ts:304:16)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at NextDevInstance.patchFile (lib/next-modes/base.ts:742:9)
  at NextDevInstance.patchFile (lib/next-modes/next-dev.ts:304:16)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:251:13)
  at NextDevInstance.patchFile (lib/next-modes/base.ts:742:9)
  at NextDevInstance.patchFile (lib/next-modes/next-dev.ts:304:16)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:213:9)
  at Object.withChange (e2e/filesystem-cache/filesystem-cache.test.ts:296:13)
  at Object.<anonymous> (e2e/filesystem-cache/filesystem-cache.test.ts:375:11)

@codspeed-hq
Copy link

codspeed-hq bot commented Feb 25, 2026

Merging this PR will not alter performance

✅ 17 untouched benchmarks
⏩ 3 skipped benchmarks1


Comparing sokra/env-in-cache (7671c5d) with canary (67bb800)

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@nextjs-bot
Copy link
Collaborator

Stats from current PR

🔴 1 regression

Metric Canary PR Change Trend
Cold (First Request) 1.567s 1.688s 🔴 +121ms (+8%) ▁▃▄▄▁
📊 All Metrics
📖 Metrics Glossary

Dev Server Metrics:

  • Listen = TCP port starts accepting connections
  • First Request = HTTP server returns successful response
  • Cold = Fresh build (no cache)
  • Warm = With cached build artifacts

Build Metrics:

  • Fresh = Clean build (no .next directory)
  • Cached = With existing .next directory

Change Thresholds:

  • Time: Changes < 50ms AND < 10%, OR < 2% are insignificant
  • Size: Changes < 1KB AND < 1% are insignificant
  • All other changes are flagged to catch regressions

⚡ Dev Server

Metric Canary PR Change Trend
Cold (Listen) 913ms 914ms ▁▁▁▁▁
Cold (Ready in log) 900ms 914ms ▁▁▂▂▁
Cold (First Request) 1.567s 1.688s 🔴 +121ms (+8%) ▁▃▄▄▁
Warm (Listen) 914ms 913ms ▁▁▁▁▁
Warm (Ready in log) 904ms 911ms ▁▁▁▁▁
Warm (First Request) 726ms 705ms ▂▁▁▂▂
📦 Dev Server (Webpack) (Legacy)

📦 Dev Server (Webpack)

Metric Canary PR Change Trend
Cold (Listen) 456ms 457ms ▁▁▁▁▁
Cold (Ready in log) 439ms 438ms ▁▁▁▁▁
Cold (First Request) 1.944s 1.961s ▁▁▁▁▁
Warm (Listen) 456ms 457ms ▁▁▁▁▁
Warm (Ready in log) 439ms 438ms ▁▁▁▁▁
Warm (First Request) 1.976s 1.976s ▁▁▁▁▁

⚡ Production Builds

Metric Canary PR Change Trend
Fresh Build 6.396s 6.696s ▁▁▁▁▁
Cached Build 6.340s 6.625s ▁▁▁▁▁
📦 Production Builds (Webpack) (Legacy)

📦 Production Builds (Webpack)

Metric Canary PR Change Trend
Fresh Build 14.166s 14.124s ▁▁▄▁▃
Cached Build 14.175s 14.165s ▁▁▃▁▃
node_modules Size 474 MB 474 MB █████
📦 Bundle Sizes

Bundle Sizes

⚡ Turbopack

Client

Main Bundles: **399 kB** → **399 kB** ✅ -8 B

80 files with content-based hashes (individual files not comparable between builds)

Server

Middleware
Canary PR Change
middleware-b..fest.js gzip 766 B 761 B
Total 766 B 761 B ✅ -5 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 448 B 451 B
Total 448 B 451 B ⚠️ +3 B

📦 Webpack

Client

Main Bundles
Canary PR Change
5528-HASH.js gzip 5.54 kB N/A -
6280-HASH.js gzip 57.5 kB N/A -
6335.HASH.js gzip 169 B N/A -
912-HASH.js gzip 4.59 kB N/A -
e8aec2e4-HASH.js gzip 62.6 kB N/A -
framework-HASH.js gzip 59.7 kB 59.7 kB
main-app-HASH.js gzip 256 B 254 B
main-HASH.js gzip 39.1 kB 39.1 kB
webpack-HASH.js gzip 1.68 kB 1.68 kB
262-HASH.js gzip N/A 4.59 kB -
2889.HASH.js gzip N/A 169 B -
5602-HASH.js gzip N/A 5.55 kB -
6948ada0-HASH.js gzip N/A 62.6 kB -
9544-HASH.js gzip N/A 58.3 kB -
Total 231 kB 232 kB ⚠️ +754 B
Polyfills
Canary PR Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Total 39.4 kB 39.4 kB
Pages
Canary PR Change
_app-HASH.js gzip 194 B 194 B
_error-HASH.js gzip 183 B 180 B 🟢 3 B (-2%)
css-HASH.js gzip 331 B 330 B
dynamic-HASH.js gzip 1.81 kB 1.81 kB
edge-ssr-HASH.js gzip 256 B 256 B
head-HASH.js gzip 351 B 352 B
hooks-HASH.js gzip 384 B 383 B
image-HASH.js gzip 580 B 581 B
index-HASH.js gzip 260 B 260 B
link-HASH.js gzip 2.5 kB 2.5 kB
routerDirect..HASH.js gzip 320 B 319 B
script-HASH.js gzip 386 B 386 B
withRouter-HASH.js gzip 315 B 315 B
1afbb74e6ecf..834.css gzip 106 B 106 B
Total 7.97 kB 7.97 kB ✅ -2 B

Server

Edge SSR
Canary PR Change
edge-ssr.js gzip 125 kB 125 kB
page.js gzip 253 kB 253 kB
Total 377 kB 378 kB ⚠️ +508 B
Middleware
Canary PR Change
middleware-b..fest.js gzip 617 B 613 B
middleware-r..fest.js gzip 156 B 155 B
middleware.js gzip 43.8 kB 43.9 kB
edge-runtime..pack.js gzip 842 B 842 B
Total 45.4 kB 45.5 kB ⚠️ +85 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 715 B 718 B
Total 715 B 718 B ⚠️ +3 B
Build Cache
Canary PR Change
0.pack gzip 3.99 MB 4 MB 🔴 +12.5 kB (+0%)
index.pack gzip 102 kB 102 kB
index.pack.old gzip 101 kB 102 kB
Total 4.19 MB 4.2 MB ⚠️ +14.4 kB

🔄 Shared (bundler-independent)

Runtimes
Canary PR Change
app-page-exp...dev.js gzip 318 kB 318 kB
app-page-exp..prod.js gzip 169 kB 169 kB
app-page-tur...dev.js gzip 318 kB 318 kB
app-page-tur..prod.js gzip 168 kB 168 kB
app-page-tur...dev.js gzip 314 kB 314 kB
app-page-tur..prod.js gzip 167 kB 167 kB
app-page.run...dev.js gzip 315 kB 315 kB
app-page.run..prod.js gzip 167 kB 167 kB
app-route-ex...dev.js gzip 70.8 kB 70.8 kB
app-route-ex..prod.js gzip 49.2 kB 49.2 kB
app-route-tu...dev.js gzip 70.8 kB 70.8 kB
app-route-tu..prod.js gzip 49.2 kB 49.2 kB
app-route-tu...dev.js gzip 70.4 kB 70.4 kB
app-route-tu..prod.js gzip 49 kB 49 kB
app-route.ru...dev.js gzip 70.4 kB 70.4 kB
app-route.ru..prod.js gzip 49 kB 49 kB
dist_client_...dev.js gzip 324 B 324 B
dist_client_...dev.js gzip 326 B 326 B
dist_client_...dev.js gzip 318 B 318 B
dist_client_...dev.js gzip 317 B 317 B
pages-api-tu...dev.js gzip 43.2 kB 43.2 kB
pages-api-tu..prod.js gzip 32.9 kB 32.9 kB
pages-api.ru...dev.js gzip 43.2 kB 43.2 kB
pages-api.ru..prod.js gzip 32.8 kB 32.8 kB
pages-turbo....dev.js gzip 52.5 kB 52.5 kB
pages-turbo...prod.js gzip 38.5 kB 38.5 kB
pages.runtim...dev.js gzip 52.5 kB 52.5 kB
pages.runtim..prod.js gzip 38.4 kB 38.4 kB
server.runti..prod.js gzip 62 kB 62 kB
Total 2.81 MB 2.81 MB ⚠️ +3 B
📎 Tarball URL
next@https://vercel-packages.vercel.app/next/prs/90526/next

common_node_env filters env vars to a small known set (NODE_*, UV_*,
SSL_*) that are safe to cache, so it should return a persistable EnvMap.
@sokra sokra changed the title Add TransientEnvMap to avoid persisting env vars in cache Turbopack: Add TransientEnvMap to avoid persisting env vars in cache Feb 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

created-by: Turbopack team PRs by the Turbopack team. Turbopack Related to Turbopack with Next.js.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants