honojs / hono

Web framework built on Web Standards
https://hono.dev
MIT License
19.79k stars 562 forks source link

Memory leak with `hono`, `@hono/node-server`, `@hono/graphql-server` #2816

Closed kyscott18 closed 4 months ago

kyscott18 commented 5 months ago

What version of Hono are you using?

4.3.10

What runtime/platform is your app running on?

Node

What steps can reproduce the bug?

import { Hono } from "hono";
import { serve } from "@hono/node-server";
import { graphqlServer } from "@hono/graphql-server";
import { buildSchema } from "graphql";

setInterval(() => {
  const before = process.memoryUsage().heapUsed / 1024 / 1024;
  global.gc?.();
  const after = process.memoryUsage().heapUsed / 1024 / 1024;
  console.log({ before: before.toFixed(2), after: after.toFixed(2) });
}, 1_000);

export const app = new Hono();

const schema = buildSchema(`
type Query {
  hello: String
}
`);

const rootResolver = (ctx) => {
  return {
    hello: () => "Hello Hono!",
  };
};

app.use(
  "/graphql",
  graphqlServer({
    schema,
    rootResolver,
  })
);

serve(app);

What is the expected behavior?

No response

What do you see instead?

Result of running the server and then sending requests with autocannon after a few seconds:

autocannon -c 100 -d 10 -m POST -H "Content-Type: application/json" -b '{"query":"{ hello }"}' http://localhost:3000/graphql
(base) kylescott@Kyles-MacBook-Pro-2 hono-node-repro % node --expose-gc index.js
{ before: '8.86', after: '6.72' }
{ before: '6.83', after: '6.75' }
{ before: '6.77', after: '6.75' }
{ before: '6.77', after: '6.75' }
{ before: '6.82', after: '6.76' }
{ before: '6.78', after: '6.76' }
{ before: '6.83', after: '6.77' }
{ before: '55.64', after: '37.63' }
{ before: '153.87', after: '97.79' }
{ before: '205.73', after: '152.70' }
{ before: '262.65', after: '208.79' }
{ before: '310.95', after: '259.03' }
{ before: '355.99', after: '308.32' }
{ before: '400.77', after: '354.94' }
{ before: '444.92', after: '398.86' }
{ before: '489.06', after: '443.80' }
{ before: '523.01', after: '484.06' }
{ before: '565.09', after: '523.40' }

Additional information

https://github.com/kyscott18/hono-node-mem-leak

Pretty sure the memory for the request body is what is being leaked, not sure if it is related to GraphQL at all. I was able to fix this issue locally by removing the call to Readable.toWeb() in this file. https://github.com/honojs/node-server/blob/main/src/request.ts#L67

usualoma commented 5 months ago

@kyscott18 Thank you! Oh, this needs to be fixed. I will check.

yusukebe commented 4 months ago

This was fixed by https://github.com/honojs/node-server/pull/172. Thanks!