Niklas Mischkulnig
90d · built 2026-07-24
90-day totals
- Commits
- 91
- Grow
- 3.5
- Maintenance
- 6.8
- Fixes
- 1.4
- Total ETV
- 11.7
Where this dev ranks
Percentile against the global top-100 leaderboard (all-time totals).
- By commits
- Top 32 %
- By Growth share
- Top 90 %
30-day trajectory
Last 30 days vs. the 30 days before. Up arrows on Growth and ETV mean improvement; up arrow on Fixes share means more time on fixes (worse).
↑+10.3 %
vs 29 prior
↓-2.5 pp
recent vs prior
↑+12.0 pp
recent vs prior
Daily performance
Daily ETV, stacked by Growth, Maintenance and Fixes.
Work-mix over time
Share of Growth / Maintenance / Fixes over a rolling 7-day window. Reads as 'where is effort flowing right now'.
Repository spread
Where this developer's commits land. Concentrated work (top1 > 80%) vs polymath spread (top1 < 30%).
Most impactful commits
Top 20 by ETV in the 90-day window.
- 0.9ETVTurbopack: refactor NFT to add Endpoint.traced_files (#94224) Refactor the module-graph bit of NFT so that we can provide `Endpoint.traced_files()` which is needed for the bundle analyzer There should be no logic change whatsoevergithub.com-vercel-next.js · 87ee4fe4 · 2026-06-01
- 0.8ETVTurbopack: use module graph for NFT (#92901) - [x] skip traced edges properly in all graph traversals - [x] iter_nodes and enumerate_nodes include the traced modules - [x] Don't propagate is_self_async inside of traced references as a perf optimization - [x] fix performance - [x] validate that NFT JSON files are identical - [x] ~~validate/adjust bundle analyzer output~~ will be in followup - [x] audit `fn chunking_type()` changes Benchmark: ``` * ced85b3108 - (2 weeks ago) refactor - Niklas Mischkulnig (HEAD -> mischnic/nft-module-graph, origin/mischnic/nft-module-graph) TURBOPACK_PERSISTENT_CACHE=0 NEXT_TURBOPACK_TRACING= pnpm next build 334.96s user 44.57s system 788% cpu 48.152 total TURBOPACK_PERSISTENT_CACHE=0 NEXT_TURBOPACK_TRACING= pnpm next build 343.39s user 42.61s system 809% cpu 47.659 total * 5edf48238f - (77 minutes ago) v16.3.0-canary.32 - next-js-bot[bot] (HEAD, tag: v16.3.0-canary.32) TURBOPACK_PERSISTENT_CACHE=0 NEXT_TURBOPACK_TRACING= pnpm next build 333.42s user 43.57s system 712% cpu 52.877 total TURBOPACK_PERSISTENT_CACHE=0 NEXT_TURBOPACK_TRACING= pnpm next build 332.95s user 43.15s system 791% cpu 47.515 total TURBOPACK_PERSISTENT_CACHE=0 NEXT_TURBOPACK_TRACING= pnpm next build 337.59s user 41.28s system 771% cpu 49.117 total TURBOPACK_PERSISTENT_CACHE=0 NEXT_TURBOPACK_TRACING= pnpm next build 335.25s user 45.53s system 718% cpu 52.975 total ``` <details> <summary>Previous benchmarks</summary> ``` 52212418699f362904d64c08e544d4994e8d27fa mischnic/nft-module-graph pnpm next build 371.41s user 66.39s system 737% cpu 59.353 total pnpm next build 380.13s user 59.62s system 751% cpu 58.548 total pnpm next build 374.25s user 60.55s system 761% cpu 57.102 total 8e4cfc5062 canary pnpm next build 370.77s user 53.89s system 762% cpu 55.725 total pnpm next build 383.16s user 55.61s system 744% cpu 58.921 total pnpm next build 382.34s user 53.51s system 757% cpu 57.512 total pnpm next build 381.15s user 54.50s system 751% cpu 57.943 total ``` ``` b0d5411a79 mischnic/nft-module-graph pnpm next build --experimental-build-mode=compil 368.75s user 62.05s system 749% cpu 57.445 total pnpm next build --experimental-build-mode=compil 368.95s user 58.42s system 763% cpu 56.004 total 0e3ad2768bd3b036e96f66e4b770a16bb0b38705 mischnic/nft-module-graph pnpm next build --experimental-build-mode=compil 369.48s user 60.62s system 748% cpu 57.494 total pnpm next build --experimental-build-mode=compil 374.89s user 52.27s system 730% cpu 58.449 total pnpm next build --experimental-build-mode=compil 375.02s user 52.89s system 747% cpu 57.274 total f37073e1d96f6d846cd333b93fccd1dd7bdc253e mischnic/speed-next-dynamic-map pnpm next build --experimental-build-mode=compil 389.58s user 55.98s system 704% cpu 1:03.21 total e599b11e2d6b09a92600cfca6d9b338ed1f7537d mischnic/fix-side-effect-edge-removal pnpm next build --experimental-build-mode=compil 386.60s user 53.34s system 720% cpu 1:01.09 total f68f70b0446cc698f0206acefefb51946c1c1545 canary pnpm next build --experimental-build-mode=compil 387.46s user 53.72s system 738% cpu 59.716 total pnpm next build --experimental-build-mode=compil 390.33s user 53.54s system 734% cpu 1:00.43 total pnpm next build --experimental-build-mode=compil 385.33s user 56.55s system 722% cpu 1:01.18 total pnpm next build --experimental-build-mode=compil 386.49s user 56.44s system 726% cpu 1:00.96 total ``` ``` b1ed4553e6 origin/mischnic/nft-module-graph pnpm next build --experimental-build-mode=compile 467.28s user 75.24s system 791% cpu 1:08.56 total pnpm next build --experimental-build-mode=compile 465.00s user 76.80s system 831% cpu 1:05.20 total pnpm next build --experimental-build-mode=compile 473.86s user 70.73s system 790% cpu 1:08.90 total 3cb77c844b canary pnpm next build --experimental-build-mode=compile 367.91s user 58.06s system 726% cpu 58.672 total pnpm next build --experimental-build-mode=compile 362.97s user 57.68s system 746% cpu 56.379 total pnpm next build --experimental-build-mode=compile 364.59s user 57.01s system 724% cpu 58.167 total ``` </details>github.com-vercel-next.js · 5ee70052 · 2026-05-28
- 0.6ETVTurbopack: fix bundle-analyzer for NFT change (#93363) We have no testing infrastructure, unfortunately <img width="2254" height="1260" alt="Bildschirmfoto 2026-05-28 um 20 29 58" src="https://github.com/user-attachments/assets/a9f1b646-994d-4417-98d7-160ce5249032" />github.com-vercel-next.js · 0e6f52e9 · 2026-06-02
- 0.6ETVTurbopack: fixup cache handler tracing (#94477) https://github.com/vercel/next.js/pull/94197 had a bug in the Turbopack case, where it didn't properly trace all necessary files referenced from `cacheHandler` and `cacheHandlers`. If you imported `lodash` in the cache handler, then - `node_modules/.pnpm/lodash@4.18.1/node_modules/lodash/lodash.js` was correctly traced but missing were - `node_modules/.pnpm/lodash@4.18.1/node_modules/lodash/package.json` and - `node_modules/lodash` (the symlink) The problem was that it wasn't including affecting sources of these entrypoints, because it was treating those entrypoints as bundled: ``` SingleModuleGraph::new_inner( entries: Vec<ChunkGroupEntry>, visited_modules: &FxIndexMap<ResolvedVc<Box<dyn Module>>, GraphNodeIndex>, include_traced: bool, include_binding_usage: bool, entries_are_traced: bool, // <------ problematic ) -> Result<Vc<Self>> ``` should really have been ``` SingleModuleGraph::new_inner( entries: &GraphEntries, // contains Vec<ChunkGroupEntry> and traced_modules: Vec<Modules visited_modules: &FxIndexMap<ResolvedVc<Box<dyn Module>>, GraphNodeIndex>, include_traced: bool, include_binding_usage: bool, ) -> Result<Vc<Self>> { ``` because the single `entries_are_traced: bool` can be different per entry.github.com-vercel-next.js · 74bb0d9a · 2026-06-05
- 0.5ETVTurbopack: compute code hash per `use cache` function (#94234) This computes the implementation hash of a given `use cache`: - it includes the module containing the `use cache` function, plus all transitive imports of that module (including externals via NFT) - what does it hash - for bundled code, it hashes the generated code (so including any AST transforms, inlined env vars, etc) - for NFTd files, it hashes the file content on disk - So this is basically equivalent to hashing the generated JS chunks, except that it's scoped to only what the given actions module uses - (so notably, if you have multiple use cache functions in a given file, then they will all have the same hash) <br/> - [x] Gate behind experimental flag - [x] Only compute hash for `use cache` functions, not all server actions - [ ] `final_read_hint` is a problem. Some chunk items are now codgened twice, so it recomputes the AST - [x] disable for dev for now - [ ] Measure perf impact ```jsonc // .next/server/server-reference-manifest.json { "node": { "806f4954cfbb75404a19d6d405065ed9059cc0cab2": { "workers": { "app/rsc/page": { "moduleId": "[project]/bench/app-router-server/.next-internal/server/app/rsc/page/actions.js { ACTIONS_MODULE0 => \"[project]/bench/app-router-server/app/rsc/logic.js [app-rsc] (ecmascript)\" } [app-rsc] (server actions loader, ecmascript)", "async": false, "exportedName": "$$RSC_SERVER_CACHE_0", "filename": "bench/app-router-server/app/rsc/logic.js", "codeHash": "413e394d9597b35df12828a6a7fd6363" // <------------ } }, "filename": "bench/app-router-server/app/rsc/logic.js", "exportedName": "$$RSC_SERVER_CACHE_0" } }, "edge": {}, "encryptionKey": "jOF2TbpNLjp2oOhl3VPBwGE7luodnei9clJPq/gaYQo=" } ```github.com-vercel-next.js · 84457f4e · 2026-06-30
- 0.5ETVProperly set response-based OTEL attributes with adapters (#94603) **Ignore whitespace changes when viewing the diff** This fixes some of the failures (particularly the ones where a 500 returned from an App API route showed up as status:200 in OTEL). But the newly added tests have more failures that I skipped for now 1. Missing `setStatus` call 2. Attribute handling was too early, before `sendResponse` was called: https://github.com/vercel/next.js/blob/6f4d94ac889db3d23a77847ec4f3a9dadf9dd775/packages/next/src/build/templates/app-route.ts#L289-L296 ```js return routeModule.handle(nextReq, context).finally(() => { // <-- handle() returns the response object from the user code if (!span) return span.setAttributes({ 'http.status_code': res.statusCode, // <---------- this is using some default response object, not what handle() returned 'next.rsc': false, }) ```github.com-vercel-next.js · 37e9d099 · 2026-06-16
- 0.4ETVTurbopack: constant evaluate `x in y` (#95286) Prerequisite for https://github.com/vercel/next.js/pull/95233 Constant evaluation of ```js if (!('NODE_ENV' in process.env)) { console.log('existing') } console.log('NODE_ENV' in process.env) ``` -> ```js if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable ; console.log(("TURBOPACK compile-time value", true)); ```github.com-vercel-next.js · 26ba3607 · 2026-06-30
- 0.4ETVRespect NEXT_HASH_SALT for server side assetsHashes (#95738) Also respect the hash salt for `assetsHashes`github.com-vercel-next.js · b3480cfd · 2026-07-15
- 0.4ETVFix instrumentation hook awaiting for middleware with adapters (#95357) #94306 fixes this for pages, but middleware was still broken when deployed via adapters Coming from https://github.com/getsentry/sentry-javascript/issues/21713 Now the instrumentation test suite takes 11m to run in deployment mode though....github.com-vercel-next.js · 70165e9d · 2026-07-06
- 0.3ETVTurbopack: iter_reachable_modules (#93315) Add `iter_reachable_modules` and `iter_reachable_nodes`. They actually respect unused referencesgithub.com-vercel-next.js · 28c9eefa · 2026-04-28
- 0.3ETVotel: Use correct parent span for Node.js middleware (#95306) Node.js Middleware was inheriting the wrong parent span (and behaved differently compared to Edge runtime Middleware) `Middleware.execute` and `BaseServer.handleRequest` should be sibling spans (depending on context, both are root spans). Previously `BaseServer.handleRequest` had a child span `Middleware.execute` Depends on https://github.com/vercel/next.js/pull/95357 to make the direct entrypoint test passgithub.com-vercel-next.js · c2b51426 · 2026-07-06
- 0.3ETVInclude deployment id in `cacheHandlers` keys (#93453) How was this ever working for dev? In that case, `buildId = "development"` and so it always uses the same cache keygithub.com-vercel-next.js · 07f76411 · 2026-05-04
- 0.3ETVTurbopack: compute exports without full analysis (#92823) We don't actually need the full analysis to compute exports. This can break some task cycles, and might theoretically improve task latency. The CPU time appears to be marginally higher (but not statistically significant), but no impact on overall build time: ``` * c4fdcc2651 - (14 hours ago) compute exports before final_read_hint() - Niklas Mischkulnig (origin/mischnic/get-exports-without-analyze, mischnic/get-exports-without-analyze) pnpm next build --experimental-build-mode=compile 378.10s user 58.28s system 760% cpu 57.411 total pnpm next build --experimental-build-mode=compile 383.64s user 60.32s system 738% cpu 1:00.10 total pnpm next build --experimental-build-mode=compile 378.70s user 55.65s system 718% cpu 1:00.41 total * 8ddc1cdbdd - (38 minutes ago) Use OIDC for CodSpeed (#93059) - Niklas Mischkulnig (origin/canary, origin/HEAD, canary) pnpm next build --experimental-build-mode=compile 376.95s user 58.30s system 755% cpu 57.597 total pnpm next build --experimental-build-mode=compile 375.85s user 61.75s system 738% cpu 59.230 total pnpm next build --experimental-build-mode=compile 377.75s user 63.00s system 729% cpu 1:00.39 total ```github.com-vercel-next.js · eb763918 · 2026-04-28
- 0.3ETVTurbopack: don't run NFT for output:export or Edge (#94862) - For `output: export`, there is no server (only SSG). So no need for NFT - For Edge, there are no files. So no need for NFTgithub.com-vercel-next.js · 8b24a83d · 2026-06-17
- 0.3ETVTurbopack: refactor to use `get_ecma_transform_rule` (#94485) Use a util function insteadgithub.com-vercel-next.js · 87ce7a7a · 2026-06-05
- 0.3ETVAdd nextConfig.instrumentationClientInject (#93785) This allows injecting client bootstrap code using only next.config.js (without writing to any user source files).github.com-vercel-next.js · 944e4548 · 2026-05-19
- 0.2ETVTurbopack: expose hashes of source files to adapters (#93539) - [x] fix tests - [ ] add experimental flag and only enable in adapter? or is this cheap enough to just always do? - [x] disable for webpack Closes PACK-6541 For https://github.com/nextjs/adapter-vercel/pull/24 Newer version of https://github.com/vercel/next.js/pull/89534 - Add a hashes mapping to the NFT file - Forward that information to the adapter via `assetsHashes` for functions Basically zero-cost: ``` commit ad728b15a6431a6372eea3d3d766b328569811b4 (HEAD -> mischnic/server-paths-manifest-2, origin/mischnic/server-paths-manifest-2) pnpm next build 351.22s user, 51.55s system, 811% cpu, 49.654 total pnpm next build 354.52s user, 53.39s system, 837% cpu, 48.706 total pnpm next build 344.02s user, 63.62s system, 749% cpu, 54.368 total pnpm next build 353.74s user, 54.25s system, 833% cpu, 48.970 total commit 04294cb47a6d67adf73c8b6f196ed6a2ddcb2b0e (origin/canary, origin/HEAD) pnpm next build 344.24s user, 53.88s system, 798% cpu, 49.845 total pnpm next build 340.89s user, 52.40s system, 784% cpu, 50.138 total pnpm next build 347.26s user, 51.91s system, 802% cpu, 49.741 total pnpm next build 347.04s user, 52.65s system, 803% cpu, 49.764 total ```github.com-vercel-next.js · 9a48c22c · 2026-05-11
- 0.2ETVTurbopack: show codeframe when tracing too much (#94207) Finally, we can show a codeframe <img width="1204" height="774" alt="Bildschirmfoto 2026-05-28 um 21 16 35" src="https://github.com/user-attachments/assets/a70c1fce-8a86-472a-9904-28f181d32385" />github.com-vercel-next.js · 2ae01a84 · 2026-06-01
- 0.2ETVTurbopack: don't generate next-server.js.nft.json with adapters (#93684) Adapters don't read these files. Also added a snapshot test similar to the existing ones to not regress on function sizegithub.com-vercel-next.js · 554b7fe3 · 2026-05-11
- 0.2ETVMove immutable static assets config option out of experimental (#95351) Keep reading `config.experimental.supportsImmutableAssets` for now to not break existing adapters until they are migrated. Closes NAR-868github.com-vercel-next.js · 756d6dc9 · 2026-07-20