I have a Nuxt 3 production app hosted on Scalingo (it's like Heroku but is a french company)
I have so many container crashes because of memory issues when a lot of people are browsing the website. There are 3 containers of size M which is 512 Mb of RAM
I use Nuxt for SSR, as well as for image serving, here are the enabled modules:
modules: [
'nuxt-auth-sanctum',
'@vesp/nuxt-fontawesome',
'@nuxtjs/google-fonts',
'@nuxt/eslint',
'@nuxt/icon',
'nuxt-jsonld',
'@pinia/nuxt',
'dayjs-nuxt',
'@vee-validate/nuxt',
'@element-plus/nuxt',
'@nuxtjs/i18n',
'@nuxtjs/robots',
'@sentry/nuxt/module',
'@nuxt/image',
],
I saw in v3 to v4 docs :
Nuxt's data fetching system (useAsyncData and useFetch) has been significantly reorganized for better performance and consistency:
...
Data cleanup: When the last component using data fetched with useAsyncData is unmounted, Nuxt will remove that data to avoid ever-growing memory usage.
I use useAsyncData on many pages so here is why I feel concerned about this upgrade. Do you think it would fix the memory problem ?
In this application, we also have scraping issues. The website is not protected with a firewall, and gets scraped a lot even if we have software rate-limits.
I am really tired of losing time managing this, because my main job is to develop applications, not deploy them. Scalingo is really helpful, providing CD, but their job stops here.
We were trying to add Cloudflare, but the requests from SSR were getting blocked, because some of the requests (managed by a package: nuxt-auth-sanctum) were not passing headers from client to the server, including User-Agent, X-Forwarded-For (app is behind an nginx proxy). So we had to rollback.
For the package nuxt-auth-sanctum to be configurable, I needed to upgrade it, but it also needed a newer version from @nuxt. By doing that upgrade, it worked fine in local and dev servers, but as soon a I pushed to production, we had a lot more memory issues.
On the graph, the 2 first days are on nuxt@3.15.2, the last day is on nuxt@3.19.2
.
Basically, I could try not to upgrade nuxt-auth-sanctum and try with the old fashioned way to intercept outgoing requests, but that would not fix the memory usage.
BTW, I tried to add --max-old-space-size=512 but that's the default value, and the program still crash with the following error :
2025-09-23 10:53:08.052956493 +0200 CEST [web-2] <--- Last few GCs --->
2025-09-23 10:53:08.052959859 +0200 CEST [web-2] [22:0x5ee30d0] 67872 ms: Mark-Compact 248.7 (258.6) -> 247.6 (258.8) MB, 120.54 / 0.01 ms (average mu = 0.235, current mu = 0.256) allocation failure; scavenge might not succeed
2025-09-23 10:53:08.052961144 +0200 CEST [web-2] [22:0x5ee30d0] 68006 ms: Mark-Compact 248.8 (258.8) -> 247.6 (258.8) MB, 103.25 / 0.01 ms (average mu = 0.230, current mu = 0.225) allocation failure; scavenge might not succeed
2025-09-23 10:53:08.052961497 +0200 CEST [web-2] <--- JS stacktrace --->
2025-09-23 10:53:08.052991423 +0200 CEST [web-2] FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
2025-09-23 10:53:08.052991888 +0200 CEST [web-2] ----- Native stack trace -----
2025-09-23 10:53:08.056884118 +0200 CEST [web-2] 1: 0xb76dc5 node::OOMErrorHandler(char const*, v8::OOMDetails const&) [node]
2025-09-23 10:53:08.060490071 +0200 CEST [web-2] 2: 0xee6020 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, v8::OOMDetails const&) [node]
2025-09-23 10:53:08.061078256 +0200 CEST [web-2] 3: 0xee6307 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, v8::OOMDetails const&) [node]
2025-09-23 10:53:08.061658426 +0200 CEST [web-2] 4: 0x10f7f55 [node]
2025-09-23 10:53:08.062248504 +0200 CEST [web-2] 5: 0x10f84e4 v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector) [node]
2025-09-23 10:53:08.062870141 +0200 CEST [web-2] 6: 0x110f3d4 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::internal::GarbageCollectionReason, char const*) [node]
2025-09-23 10:53:08.063501060 +0200 CEST [web-2] 7: 0x110fbec v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
2025-09-23 10:53:08.064089511 +0200 CEST [web-2] 8: 0x10e5ef1 v8::internal::HeapAllocator::AllocateRawWithLightRetrySlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [node]
2025-09-23 10:53:08.064678519 +0200 CEST [web-2] 9: 0x10e7085 v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [node]
2025-09-23 10:53:08.065247438 +0200 CEST [web-2] 10: 0x10c37a6 v8::internal::Factory::AllocateRaw(int, v8::internal::AllocationType, v8::internal::AllocationAlignment) [node]
2025-09-23 10:53:08.067200955 +0200 CEST [web-2] 11: 0x10b53d4 v8::internal::FactoryBase<v8::internal::Factory>::AllocateRawWithImmortalMap(int, v8::internal::AllocationType, v8::internal::Map, v8::internal::AllocationAlignment) [node]
2025-09-23 10:53:08.067828128 +0200 CEST [web-2] 12: 0x10b7bb6 v8::internal::FactoryBase<v8::internal::Factory>::NewRawOneByteString(int, v8::internal::AllocationType) [node]
2025-09-23 10:53:08.068463725 +0200 CEST [web-2] 13: 0x12d88c4 v8::internal::Intl::ConvertToUpper(v8::internal::Isolate*, v8::internal::Handle<v8::internal::String>) [node]
2025-09-23 10:53:08.069179612 +0200 CEST [web-2] 14: 0x1521d8e v8::internal::Runtime_StringToUpperCaseIntl(int, unsigned long*, v8::internal::Isolate*) [node]
2025-09-23 10:53:08.069862427 +0200 CEST [web-2] 15: 0x1959ef6 [node]
2025-09-23 10:53:08.299574845 +0200 CEST [web-2] scripts/run.sh: line 3: 22 Aborted (core dumped) node --import ./.output/server/sentry.server.config.mjs .output/server/index.mjs
2025-09-23 10:53:38.847166573 +0200 CEST [manager] - documentation: https://doc.scalingo.com/platform/app/crash
2025-09-23 10:53:38.847166573 +0200 CEST [manager] container [web-2] (68d25faf99826981b226f3f0) has crashed, restart container in 5m0s.
2025-09-23 10:56:36.283503886 +0200 CEST [manager] container [web-1] (68d260c299826981b226f6ca) started with the command 'scripts/run.sh'
2025-09-23 10:56:38.940877926 +0200 CEST [web-1] Listening on http://[::]:23535
2025-09-23 10:58:04.034707426 +0200 CEST [manager] container [web-3] (68d2611b99826981b226f72c) started with the command 'scripts/run.sh'
2025-09-23 10:58:05.063357052 +0200 CEST [web-3] Listening on http://[::]:29745
2025-09-23 10:58:39.509044222 +0200 CEST [manager] container [web-2] (68d2613e99c3cd69428c7698) started with the command 'scripts/run.sh'
2025-09-23 10:58:40.499286414 +0200 CEST [web-2] Listening on http://[::]:25373
Do you have any advice ?
Edit: I succeeded intercepting requests from the nuxt-auth-sanctum package and did not require to upgrade nuxt after all.
It has been 24 hours and not a single crash for now. I guess there's a memory leak between nuxt@3.15.2 and nuxt@3.19.2.
For now I'll stick with nuxt@3.15.2
Nuxt does not have a memory leak but Vue 3.5 is known to have one. It should be resolved when Vue 3.6 is released, or possibly you can pin to Vue 3.5.13 (see https://github.com/nuxt/nuxt/issues/32240).