fix: memory leak fixes for nextjs.
Addresses high memory usage by adding gzip compression to nginx (removing it from nextjs) socket cleanup handling, and tRPC client optimizations. Ref: https://github.com/homarr-labs/homarr/issues/3759
This commit is contained in:
1 parent
6a45645354
commit
c5e69c3e40
7 files changed
+41
-4
No files matched your search
@@ -19,6 +19,7 @@ const withNextIntl = createNextIntlPlugin({
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
output: "standalone",
|
||||
compress: false, // Workaround for vercel/next.js#89091 - zlib retains ServerResponse after client disconnect, causing CLOSE-WAIT socket leak
|
||||
reactStrictMode: true,
|
||||
// react compiler breaks mantine-react-table, so disabled for now
|
||||
//reactCompiler: true,
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// Periodic cleanup of zombie CLOSE-WAIT sockets in Next.js standalone mode.
|
||||
// Workaround for vercel/next.js#89091 — AfterContext retains ServerResponse
|
||||
// after client disconnect, leaving sockets in CLOSE-WAIT indefinitely.
|
||||
//
|
||||
// Usage: node --require ./socket-cleanup.cjs server.js
|
||||
// or: NODE_OPTIONS="--require /app/socket-cleanup.cjs" node server.js
|
||||
|
||||
const INTERVAL_MS = 60_000; // Check every 60 seconds
|
||||
|
||||
setInterval(() => {
|
||||
let destroyed = 0;
|
||||
for (const handle of process._getActiveHandles()) {
|
||||
if (
|
||||
handle.constructor?.name === "Socket" &&
|
||||
handle.localPort === 3000 &&
|
||||
handle.readyState === "writeOnly" &&
|
||||
!handle._httpMessage &&
|
||||
handle.bytesWritten === 0
|
||||
) {
|
||||
handle.destroy();
|
||||
destroyed++;
|
||||
}
|
||||
}
|
||||
if (destroyed > 0) {
|
||||
console.log(`[socket-cleanup] Destroyed ${destroyed} zombie socket(s)`);
|
||||
}
|
||||
}, INTERVAL_MS).unref(); // unref() so this timer doesn't prevent process exit
|
||||
@@ -7,7 +7,7 @@ import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
||||
import { ReactQueryStreamedHydration } from "@tanstack/react-query-next-experimental";
|
||||
import {
|
||||
createWSClient,
|
||||
httpBatchStreamLink,
|
||||
httpBatchLink,
|
||||
httpLink,
|
||||
isNonJsonSerializable,
|
||||
loggerLink,
|
||||
@@ -90,7 +90,7 @@ export function TRPCReactProvider(props: PropsWithChildren) {
|
||||
url: getTrpcUrl(),
|
||||
headers: createHeadersCallbackForSource("nextjs-react (form-data)"),
|
||||
}),
|
||||
false: httpBatchStreamLink({
|
||||
false: httpBatchLink({
|
||||
transformer: superjson,
|
||||
url: getTrpcUrl(),
|
||||
maxURLLength: 2083, // Suggested by tRPC: https://trpc.io/docs/client/links/httpBatchLink#setting-a-maximum-url-length
|
||||
|
||||
Reference in new issue
Block a user