oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.06k stars 2.76k forks source link

3.6x memory usage over node while running NestJS application #4796

Open kpostekk opened 1 year ago

kpostekk commented 1 year ago

What version of Bun is running?

1.0.0+822a00c4d508b54f650933a73ca5f4a3af9a7983

What platform is your computer?

Linux 6.4.13-200.fc38.x86_64 x86_64 unknown

What steps can reproduce the bug?

I run a simple NestJS application which parses input and starts a NestJS application.

The index file:

import { NestFactory } from '@nestjs/core'
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify'
import yargs from 'yargs'
import { hideBin } from 'yargs/helpers'
import { SimConf, SimConfig } from './sim/sim.config'
import { faker } from '@faker-js/faker'

function randomEVN() {
  return `${'50'} ${'51'} ${faker.helpers.arrayElement([
    '29',
    '21',
    '20',
    '84',
    '39',
    '88',
    '78',
  ])}-${'78'} ${faker.number
    .int({ min: 1, max: 999 })
    .toString()
    .padStart(3, '0')}-${faker.number.int({ min: 0, max: 9 }).toString()}`
}

yargs(hideBin(process.argv))
  .command(
    'start',
    'Start the server',
    () => {},
    async () => {
      const { AppModule } = await import('./app.module')

      const app = await NestFactory.create<NestFastifyApplication>(
        AppModule,
        new FastifyAdapter(),
      )

      app.enableShutdownHooks()
      app.enableCors()

      await app.listen(3000, '0.0.0.0')
    },
  )
  .command(
    'simulator',
    'Start the simulator',
    (y) =>
      y
        .option('url', { type: 'string' })
        .option('skipMirroring', { type: 'boolean', default: false })
        .option('failureRate', { alias: 'f', type: 'number', default: 0.025 }),
    async (args) => {
      const { SimModule } = await import('./sim/sim.module')

      const config = new SimConf()
      const url = args.url ?? config.store.url

      for (const vehicle of config.store.vehicles) {
        for (const edge of vehicle.edgeServers) {
          NestFactory.createApplicationContext(
            SimModule.forRoot(vehicle, edge, url),
          ).then(async (sim) => {
            await sim.init()
          })
        }
      }
    },
  )
  .command(
    'sim-init',
    'Initialize sim config.',
    (y) =>
      y
        .option('vehiclesCount', {
          type: 'number',
          alias: 'vc',
          default: 1,
        })
        .option('serverCount', { type: 'number', alias: 'sc', default: 1 })
        .option('displayCount', { type: 'number', alias: 'dc', default: 8 })
        .option('seed', { type: 'number' }),
    async (args) => {
      const c = new SimConf()

      if (args.seed) faker.seed(args.seed)

      const vehicles: typeof c.store.vehicles = Array.from({
        length: args.vehiclesCount,
      }).map(() => ({
        evn: randomEVN(),
        vn: faker.number.int({ min: 1, max: 99 }).toString().padStart(2, '0'),
        vt: faker.helpers.arrayElement(['01', '02', '03', '04', '05']),
        edgeServers: Array.from({ length: args.serverCount }).map(() => ({
          id: faker.string.uuid(),
          serial: faker.string.alphanumeric(18),
          displays: Array.from({ length: args.displayCount }).map(() => ({
            id: faker.string.uuid(),
            serial: faker.string.alphanumeric(18),
          })),
        })),
      }))

      c.set('vehicles', vehicles)

      console.log(c.path)
      // c.set('vehicles', [] satisfies SimConfig['vehicles'])
    },
  )
  .demandCommand()
  .parse()

The SimModule has one service, which periodically calls GraphQL api.

dist/index.js is build result from tsc.

What is the expected behavior?

Ram usage similar to node: image

What do you see instead?

3.6x of previous result: image

Additional information

The OS is Fedora 38 Server in a KVM, headless. Relates to #1641

Jarred-Sumner commented 1 year ago

likely a memory leak of some kind

venki786 commented 1 year ago

For me also, While before using Bun previous versions same/less memory utilisation comparing to Node.js. But since after upgrading to Bun 1.0.0, Memory utilisation reached double 2x. Definitely a memory leak I think.

wavded commented 1 year ago

FWIW, I've noticed a similar memory leak when switching a simple ExpressJS application over from NodeJS (running Bun 1.0.1). The first half of graph was when it was on NodeJS, the second half is after we switched to Bun.

Screenshot 2023-09-14 at 8 53 53 AM

We have another application running 0.8.1 and it is not leaking memory, so more evidence that it may be a recently introduced bug.

co-sic commented 1 year ago

I just successfully migrated a express nodejs app to bun and the memory consumption increased from 200 MiB to arround 600 MiB. :cry: Bun version 1.0.1.

Jarred-Sumner commented 1 year ago

We will prioritize reducing memory usage in the coming weeks. Might be like two weeks though

lost22git commented 1 year ago

same problem ;-) but with prisma

bun version: Both v1.0.0 and v1.0.1

It must be a memory leak, because the memory will continue to grow without an upper limit with each benchmark

bombardier --fasthttp -c 1000  -d 60s http://127.0.0.1:3000/

Screenshot 2023-09-16 210905

nikhilro commented 1 year ago

Ran into a memory leak today. +1 to prioritizing fixing memory issues. Scared to adopt Bun in production.

tomerh2001 commented 1 year ago

+1 I tried to deploy to my AWS development env and encountered an out of memory error - according to my tests, my bun build (base image = oven/bun) required ~600 MB while my dev only has 500 MB.

Comparing that to my node build, which required ~100 MB - is this the expected behavior of bun or a bug?

trychen commented 1 year ago

My Remix application with Bun.serve cost more than 5GB in 10 min, generateHeapSnapshot() didn't show no memory leak in my code. Comparing to NodeJS, which only use ~250MB without any memory leaks.

Jarred-Sumner commented 1 year ago

yeah we will work on this stuff soon, currently focused on bun install workspace-related issues and then will circle back to this

RaresAil commented 1 year ago

Hey, also want to share my findings 😄 , i am using the websocket form Bun, and when the app is build with bun build it uses twice of the ram, and when i run the ts file directly it uses the same amount of ram on a Debian system and less ram on a MacOS, the cpu is very low compared to node but that one also is higher when build

Build

image

Run TS

image
SDCore commented 1 year ago

Can also confirm. Switching from node to bun, memory went up almost 3 times and increased rather quickly compared to Node

Screenshot 2023-10-01 at 4 14 51 PM
bnol commented 1 year ago

Hi all,

Did Bun v1.0.4

fix this issue?

RaresAil commented 1 year ago

@bnol hey, not in my case, i am using web sockets and the built version is still double

wavded commented 1 year ago
Screenshot 2023-10-05 at 8 04 27 AM

I've been running this since the release. At first it looked like nothing was going to change but it does seem to be maintaining a lower level of memory over all. NodeJS is still less though by about 15MB.

co-sic commented 1 year ago

@bnol also not for my case, still triple the memory of nodejs (using express server with graphql and postgres DB)

tomerh2001 commented 1 year ago

Not for me, I couldn't even start the process, bun is using all of my ec2 memory and it crashes before staring

Also I don't even use the serve function

SDCore commented 1 year ago

1.0.4 seems to be using slightly less than 1.0.3, but still about 130mb compared to 50mb I had with pure node. I'm using fetch, though, so I don't know if the changes in 1.0.4 actually apply to me

RaresAil commented 1 year ago

Hi all,

Did Bun v1.0.4

fix this issue?

i managed to reduce the ram from bun with this build script, now the used ram at start from 70 MB ram dropped to 30mb ram, idk why by running the the build command before it had double ram

const result = await Bun.build({
  entrypoints: ['./app/index.ts'],
  outdir: './dist',
  minify: true,
  target: 'bun',
  external: ['@supabase/supabase-js']  // This dep is not supported with bun
});

if (!result.success) {
  console.error(...result.logs);
  process.exit(-1);
}

console.log(...result.logs);
wavded commented 1 year ago

Bun v1.0.4 dropped usage almost in half for me, but the recent Bun v1.0.7 doubled it again. Continuing to monitor but it almost looks like a memory leak to me:

Screenshot 2023-10-24 at 7 52 48 AM
Jarred-Sumner commented 1 year ago

You should see it drop a little bit in Bun v1.0.8 thanks to fixing a memory leak in require()

For the same Nest.js "hello world" app:

Node.js v20.8.0: 67 MB Bun v1.0.8: 76 MB Bun v1.0.7: 110 MB

We still have more work to do to fully address this issue.

anistark commented 3 months ago

We're still facing heavy memory leak problem on bun v1.1.21

Anybody found any workaround or fix or debugged? Any pointers appreciated.

co-sic commented 2 months ago

For us the memory consumption is also still a lot higher compared to node, even on the latest bun version.