sentry-javascript icon indicating copy to clipboard operation
sentry-javascript copied to clipboard

Slow build-times and Webpack serialization performance warnings when using `@sentry/nextjs`

Open scobbe opened this issue 11 months ago • 37 comments

⚠️ Edit by @lforst: This issue is confirmed. Please see https://github.com/getsentry/sentry-javascript/issues/15100#issuecomment-2732790153 for more information on why builds are slow when adding the Sentry SDK, and for temporary workarounds until performance issues are fixed within the SDK.

Is there an existing issue for this?

  • [x] I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
  • [x] I have reviewed the documentation https://docs.sentry.io/
  • [x] I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/nestjs

SDK Version

8.50.0

Framework Version

React 19.0.0, Next 15.1.4, Node 22.9.0

Link to Sentry event

No response

Reproduction Example/SDK Setup

Description

When adding Sentry configuration to next.config.ts using withSentryConfig, I encounter the following warning during the build process:

<w> [webpack.cache.PackFileCacheStrategy] Serializing big strings (318kiB) impacts deserialization performance (consider using Buffer instead and decode when needed)

Is this a known issue? Are there any recommendations for addressing this warning, such as additional configuration options or workarounds?

Thank you!

Steps to Reproduce

  1. Start with a minimal next.config.ts file:

    import type { NextConfig } from "next";
    
    const nextConfig: NextConfig = {};
    
    export default nextConfig;
    
  2. Update the file to include Sentry's configuration using withSentryConfig:

    import type { NextConfig } from "next";
    
    import { withSentryConfig } from "@sentry/nextjs";
    
    const nextConfig: NextConfig = {};
    
    export default withSentryConfig(nextConfig, {
      automaticVercelMonitors: true,
      disableLogger: true,
      hideSourceMaps: true,
      org: "MyOrg",
      project: "javascript-nextjs",
      reactComponentAnnotation: {
        enabled: true,
      },
      silent: !process.env.CI,
      sourcemaps: {
        deleteSourcemapsAfterUpload: true,
        disable: process.env.NODE_ENV === "development",
      },
      tunnelRoute: "/monitoring",
      widenClientFileUpload: true,
    });
    
  3. Run the build process.

Expected Result

The build completes without warnings or errors.

Actual Result

The following warning appears during the build process:

<w> [webpack.cache.PackFileCacheStrategy] Serializing big strings (318kiB) impacts deserialization performance (consider using Buffer instead and decode when needed)

scobbe avatar Jan 20 '25 22:01 scobbe

Hello @scobbe, thank you for filing this.

Could you please provide a reproduction repo? I tried setting up a new nextjs project using npx create-next-app@latest and setting Sentry up using npx @sentry/wizard@latest -i nextjs but did not run into any such warnings.

andreiborza avatar Jan 21 '25 14:01 andreiborza

same issue here with same env , however do not have reproduction repo sadly

kimdanielarthur-cowlabs avatar Jan 23 '25 16:01 kimdanielarthur-cowlabs

Same issue here. Only happened when I added sentry in and the build (running npm run dev) now takes a LOT longer.

Versions:

"@sentry/nextjs": "^8.51.0",
"next": "14.2.16",

aaa3334 avatar Jan 26 '25 01:01 aaa3334

We still need a reproduction for this to investigate further. Thanks!

Lms24 avatar Jan 27 '25 08:01 Lms24

I finally reproduced it!

https://github.com/MonstraG/sentry-webpack-strings-bug

  1. Before trying anything, make sure to remove .next folder. Repeated build attempts make the warning go away sometimes
  2. ALL of the following are required for the issue to occur:
  • sentry is set up (instrumentation.ts, sentry.client.config.ts and withSentryConfig in next.config)
  • middleware.ts is present (even completely empty file)
  • (sic!) app router folder is not in src/app but directly in the root of the project. (see last commit in repro)

MonstraG avatar Feb 10 '25 17:02 MonstraG

@MonstraG awesome, thanks for reproducing this reliably. We'll investigate.

andreiborza avatar Feb 11 '25 20:02 andreiborza

@MonstraG - This was on my to do list for today - thank you!

I have also been having this issue and I also have been experiencing the site to be a LOT slower than before.

Note the error seems to be happening on the edge side

Webpack Bundle Analyzer saved report to /Users/a/Documents/Automations/front-end-some/website/.next/analyze/nodejs.html Webpack Bundle Analyzer saved report to /Users/a/Documents/Automations/front-end-some/website/.next/analyze/edge.html [webpack.cache.PackFileCacheStrategy] Serializing big strings (318kiB) impacts deserialization performance (consider using Buffer instead and decode when needed) Webpack Bundle Analyzer saved report to /Users/a/Documents/Automations/front-end-some/website/.next/analyze/client.html

(Just incase it helps, my versions are: Sentry version: 8.54.0 Next version: 14.2.23 )

aaa3334 avatar Feb 11 '25 22:02 aaa3334

Hi, since this is just a warning and webpack will phase out eventually we will not make this a priority. If anybody does some investigations and has suggestions on how to fix we are ready to implement them!

lforst avatar Feb 12 '25 08:02 lforst

same issue here, im using sentry wizard installation also. My setup:

export default withSentryConfig(nextConfig, {
  // For all available options, see:
  // https://github.com/getsentry/sentry-webpack-plugin#options

  org: 'strategybridgeai',
  project: 'strategy-console',

  // Only print logs for uploading source maps in CI
  silent: !process.env.CI,

  // For all available options, see:
  // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/

  // Upload a larger set of source maps for prettier stack traces (increases build time)
  widenClientFileUpload: true,

  // Automatically annotate React components to show their full name in breadcrumbs and session replay
  reactComponentAnnotation: {
    enabled: true,
  },

  // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.
  // This can increase your server load as well as your hosting bill.
  // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-
  // side errors will fail.
  tunnelRoute: '/monitoring',

  // Automatically tree-shake Sentry logger statements to reduce bundle size
  disableLogger: true,

  // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)
  // See the following for more information:
  // https://docs.sentry.io/product/crons/
  // https://vercel.com/docs/cron-jobs
  automaticVercelMonitors: true,
});

Version:

{
"next": "15.1.7",
"@sentry/nextjs": "^9",
}

nabilfatih avatar Feb 21 '25 22:02 nabilfatih

Same issue here.

sengirab avatar Mar 09 '25 18:03 sengirab

I just ran into the same issue when adding sentry (which I use for all kinds of other application types) to a Next.js application. I understand it's of low priority from a PO perspective. However, for me it's a show stopper as not only production builds are affected but also dev builds. Will move to something else now.

aspnetde avatar Mar 12 '25 20:03 aspnetde

I just ran into the same issue when adding sentry (which I use for all kinds of other application types) to a Next.js application. I understand it's of low priority from a PO perspective. However, for me it's a show stopper as not only production builds are affected but also dev builds. Will move to something else now.

what's your alternative? i might want to move also... seems like no one working on this from the sentry team

nabilfatih avatar Mar 13 '25 04:03 nabilfatih

Jumping in. Tbh we weren't aware that the SDK causes so much pain wrt build times. Especially dev builds shouldn't be slowed down - at least within bounds of normal bundling. I will take a closer look at this next week.

Reminder to upgrade the SDK to the latest version if you haven't.

lforst avatar Mar 13 '25 05:03 lforst

I will probably take another look soon, but from what I can tell from yesterday's experience:

  • I was using Next.js 15.1.7
  • There's a middleware.ts present
  • Other than experienced by @MonstraG we use a ./src directory
  • We use the app router

When running next build, the message appeared (after some long process which seemed to be synchronous and blocking) as well as on the first request when using next dev. Last night, I stumbled upon https://www.reddit.com/r/nextjs/comments/16zopvr/sentry_increasing_the_size_of_first_load_js_by_2/ and will take a look if what was eventually suggested there could help.

aspnetde avatar Mar 13 '25 07:03 aspnetde

I will probably take another look soon, but from what I can tell from yesterday's experience:

  • I was using Next.js 15.1.7
  • There's a middleware.ts present
  • Other than experienced by @MonstraG we use a ./src directory

When running next build, the message appeared (after some long process which seemed to be synchronous and blocking) as well as on the first request when using next dev. Last night, I stumbled upon https://www.reddit.com/r/nextjs/comments/16zopvr/sentry_increasing_the_size_of_first_load_js_by_2/ and will take a look if what was eventually suggested there could help.

  • NextJS 15.2.1
  • We also have a middleware.ts present
  • We use the app directory
  • Noticed "clientTraceMetadata" after installing sentry, which is experimental, may be totally unrelated.

sengirab avatar Mar 13 '25 07:03 sengirab

I will probably take another look soon, but from what I can tell from yesterday's experience:

  • I was using Next.js 15.1.7
  • There's a middleware.ts present
  • Other than experienced by @MonstraG we use a ./src directory

When running next build, the message appeared (after some long process which seemed to be synchronous and blocking) as well as on the first request when using next dev. Last night, I stumbled upon https://www.reddit.com/r/nextjs/comments/16zopvr/sentry_increasing_the_size_of_first_load_js_by_2/ and will take a look if what was eventually suggested there could help.

  • NextJS 15.2.1
  • We also have a middleware.ts present
  • We use the app directory
  • Noticed "clientTraceMetadata" after installing sentry, which is experimental, may be totally unrelated.

Adding some findings to my previous reply - I can confirm that turning off the instrumentation cuts the compile time in half.

export const onRequestError = process.env.NEXT_PUBLIC_VERCEL_ENV === 'production' ? Sentry.captureRequestError : async () => {
};

Hoping this will be useful.

Image Image

sengirab avatar Mar 13 '25 12:03 sengirab

Adding some findings to my previous reply - I can confirm that turning off the instrumentation cuts the compile time in half.

I tried that, too – unfortunately it didn't do the trick. Overall the performance during dev time became unbearable at some point, so I eventually ripped out Sentry completely. Will try to come back to this next month.

aspnetde avatar Mar 15 '25 09:03 aspnetde

Ok, I had an investigative session. My process involved turning off and on certain features and seeing how they affected the build times for my test project. This is by no way scientific but it will help us understand what contributes to long build times.

The baseline for my test project is around 32 seconds for a production build. This is with all of the common features turned on (sourcemaps, react component annotations, auto wrapping, ...).

  • Removing widenClientFileUpload: true shaved off about 4 seconds
    • This is to be expected because it adds quite a bit of data that needs to be uploaded to Sentry with sourcemaps, but it should not influence compile-time (ie. dev-mode).
  • Not uploading sourcemaps to Sentry saved about 5 additional seconds
    • This number is expected to scale linearly with project size. The working theory is that this is still the biggest chunk to save build times. Although not recommended. It's also something we cannot greatly improve.
  • Turning off reactComponentAnnotation saved basically nothing.
    • It should also not affect dev-mode compilation time because it is only turned on for prod-builds.
  • Turning off middleware instrumentation with autoInstrumentMiddleware got rid of the serialization warning and saved about 1 second of compile time.
    • I suspect this is because Next.js middleware is bundled into one large file which creates a large string and the SDK comes with a bit of code and may push the warning over the edge.
    • This leads me to believe though that the serialization warning is pretty much non-consequential for build-times. 1 additional second is tolerable and I don't think this scales strongly with any other factor.
  • Turning off auto wrapping (strongly not recommended) saves about 0.5 seconds.
    • Seems rather non-consequential.
  • Turning off app router auto wrapping with autoInstrumentAppDirectory: false shaves off 5 seconds.
    • This came as a surprise. My guess is that we do our own custom bundling/compilation passes with rollup scaling with the number of app router files and file-sizes and that could end up contributing a lot.
  • Cleaning out instrumentation.ts saved about 5 seconds.
    • This is somewhat to be expected because including Sentry.init() here is actually what is gonna cause the SDK to be bundled into the server bundles. Bundling the SDK could be expensive.
    • This is not expected to scale with any user-code. The overhead should stay pretty flat, however it will add to dev-mode compile times!
  • Excluding the Sentry SDK in the client bundle saved around 1 second
    • This is done for dev builds so it may be consequential for dev mode.

Sentry adds around 20 seconds to the baseline build-time, which makes up around 60% of the total build time for my test project. Now given that my test project is not super large and many of the contributing factors shouldn't scale with project size, I can still see how that is borderline unacceptable.

Some of the Sentry features also non-trivially affect dev-mode compilation times which can be especially annoying. We gotta do something about this. I honestly hadn't noticed this too much in my own side-projects, but maybe I am walking the happy path too much.


Conclusions & next steps:

  • I feel like we can continue to ignore the Webpack serialization warning as the cause for it doesn't really contribute to build times in any consequential way.
  • Sourcemap uploading continues to be the largest build time contributor when doing production builds. I fear this is something we cannot greatly improve anymore.
    • (Edit) Next.js will likely add an afterProductionBuild hook that will allow us to run a singular sourcemap upload as opposed to three separate ones for each runtime. This will likely save some build time. (thanks @vernak2539 for raising in https://github.com/getsentry/sentry-javascript/issues/15849#issuecomment-2757683239)
  • [ ] Can we do something to speed up app router auto-wrapping? Sentry build-time contributions likely scale with application size.
  • [ ] Can we do something about the features that contribute to dev-mode compilation times (instrumentation.ts, auto-wrapping, sentry.client.config.ts)? Maybe we can adjust our copy-paste/wizard snippets to only conditionally bundle SDK code when doing a prod-build, or we provide an additional option that does some build-time magic?

Temporary improvements for people following this thread who have already successfully set up Sentry:

  • Dev mode improvements:
    • Set autoInstrumentServerFunctions, autoInstrumentMiddleware, and autoInstrumentAppDirectory to process.env.NODE_ENV === 'production'
    • Configure your instrumentation.ts file to only bundle/include the Sentry SDK for prod builds:
      // instrumentation.ts
      import { captureRequestError } from "@sentry/nextjs";
      
      export async function register() {
        if (process.env.NODE_ENV === "production") {
          if (process.env.NEXT_RUNTIME === "nodejs") {
            await import("./sentry.server.config");
          }
          if (process.env.NEXT_RUNTIME === "edge") {
            await import("./sentry.edge.config");
          }
        }
      }
      
      export const onRequestError = async (...args: [any, any, any]) => {
        if (process.env.NODE_ENV === "production") {
          captureRequestError(...args);
        }
      };
      
    • Configure your sentry.client.config.ts file to only bundle/include the Sentry SDK for prod builds:
      // sentry.client.config.ts
      import * as Sentry from "@sentry/nextjs";
      
      if (process.env.NODE_ENV === "production") {
        Sentry.init({
      	// ...
        });
      }
      
  • Prod mode improvements:
    • I cannot really recommend turning off anything except maybe sourcemaps unless visibility loss is acceptable.

lforst avatar Mar 18 '25 11:03 lforst

Configure your sentry.client.config.ts file to only bundle/include the Sentry SDK for prod builds

Only for .client? I think we should do for server.config and edge.config as well?

sanskar-19 avatar Mar 18 '25 11:03 sanskar-19

Configure your sentry.client.config.ts file to only bundle/include the Sentry SDK for prod builds

Only for .client? I think we should do for server.config and edge.config as well?

Yeah, but instrumentation.ts imports those 2, so they're excluded in that file.

sengirab avatar Mar 18 '25 11:03 sengirab

@lforst

Image

Why is there a noticible 2 min latency when running build? For me this is one of the biggest latency concerns.

sanskar-19 avatar Mar 18 '25 11:03 sanskar-19

Why is there a noticible 2 min latency when running build?

@sanskar-19 The gap is likely just Next.js compiling the Node.js part of your application. It doesn't necessarily have to do with Sentry just because the log messages are from Sentry. Afaik Next.js doesn't print anything once it completes the individual webpack build passes for the different runtimes.

lforst avatar Mar 18 '25 11:03 lforst

Configure your sentry.client.config.ts file to only bundle/include the Sentry SDK for prod builds

Only for .client? I think we should do for server.config and edge.config as well?

Yeah, but instrumentation.ts imports those 2, so they're excluded in that file.

Feels jank tbh, putting conditionals everywhere, there should be a global flag for this to prevent Sentry from being bundled in the first place.

sanskar-19 avatar Mar 18 '25 11:03 sanskar-19

@lforst to validate the same, I disabled Sentry by exporting nextConfig directly without wrapping it in withSentryConfig and guess what - I saved 2 minutes 🕐 .

Build time down to ~3 mins. So its def something from Sentry.

sanskar-19 avatar Mar 18 '25 11:03 sanskar-19

Feels jank tbh, putting conditionals everywhere

This is why it is a workaround.

@lforst to validate the same, I disabled Sentry by exporting nextConfig directly without wrapping it in withSentryConfig and guess what - I saved 2 minutes 🕐 .

Build time down to ~3 mins. So its def something from Sentry.

@sanskar-19 Please read https://github.com/getsentry/sentry-javascript/issues/15100#issuecomment-2732790153 where I acknowledge and explain this.

lforst avatar Mar 18 '25 11:03 lforst

Thanks, this investigation is very useful, and we will be applying this advice.

One quick question:

Configure your sentry.client.config.ts file to only bundle/include the Sentry SDK for prod builds:

// sentry.client.config.ts
import * as Sentry from "@sentry/nextjs";

if (process.env.NODE_ENV === "test") {
 Sentry.init({
	// ...
 });
}

Shouldn't it be "production"?

MonstraG avatar Mar 18 '25 11:03 MonstraG

Hm, so one of the workarounds to fix build time which I have is -

conditionally exporting the config on the basis of env from next.config.js. But that leads to warnings when working in local dev which I believe is because now the application is not wrapped in withSentryConfig that is why.

Is there a clean way to silent these logs out? @lforst

Import trace for requested module:
./node_modules/@opentelemetry/instrumentation/build/esm/platform/node/instrumentation.js
./node_modules/@opentelemetry/instrumentation/build/esm/platform/node/index.js
./node_modules/@opentelemetry/instrumentation/build/esm/platform/index.js
./node_modules/@opentelemetry/instrumentation/build/esm/index.js
./node_modules/@sentry/node/build/cjs/otel/instrument.js
./node_modules/@sentry/node/build/cjs/index.js

sanskar-19 avatar Mar 18 '25 11:03 sanskar-19

conditionally exporting the config on the basis of env from next.config.js. But that leads to some error logs when working in localdev which I believe is because now the application is not wrapped in withSentryConfig that is why.

This is not supported so I don't recommend doing that. withSentryConfig is part of the essential setup with the SDK. Also, the logs you're getting are not error logs, they are warnings which you can ignore for now. Technically you can configure webpack to ignore these.

lforst avatar Mar 18 '25 11:03 lforst

This is not supported so I don't recommend doing that

Fair but having said that huge build times just for every commit I push in preview envs is something very messy and unaccountable too.

So ig I need to find some common ground and make choice with recommended vs high dev speed provided conditional exporting is just for dev only.

But yea thanks for the info, will keep a check on this thread. 🙌🏻

sanskar-19 avatar Mar 18 '25 11:03 sanskar-19

Just to clarify -- is the webpack.cache.PackFileCacheStrategy a problem, regardless of whether it impacts build times? Will it be fixed?

markedwards avatar Mar 27 '25 12:03 markedwards