Chrome processes stay running after using browser.disconnect() in Puppeteer

Setup details:

  • Puppeteer: version 3.1.0
  • OS: Windows 10
  • Node: 12.16.1

The issue:

I’m scraping over 3000 websites using a loop. I connect to the same browser with puppeteer.connect and the wsEndpoint to reuse it. After visiting each site, I disconnect and close the page.

The performance gets worse as I go:

  • First 100 sites load fast
  • After 100 sites, each page needs 2-3 tries to load
  • After 300 sites, it takes 5-8 attempts per page
  • After 500+ sites, I get timeout errors constantly

When I check Task Manager, there are tons of Chrome processes still running. Each one uses about 80-90MB RAM and some CPU.

My question:

How do I properly kill these Chrome processes after calling browser.disconnect()?

Sample code:

const puppeteer = require('puppeteer')
const siteList = require('./sites.json') // 3000+ URLs

async function scrapeAll() {
  const mainBrowser = await puppeteer.launch({ headless: true })
  const endpoint = await mainBrowser.wsEndpoint()

  for (const site of siteList) {
    try {
      const connectedBrowser = await puppeteer.connect({ browserWSEndpoint: endpoint })
      const newTab = await connectedBrowser.newPage()
      await newTab.goto(site)

      // scraping logic here

      await newTab.goto('about:blank')
      await newTab.close()
      await connectedBrowser.disconnect()
    } catch (error) {
      console.log(error)
    }
  }
  await mainBrowser.close()
}
scrapeAll()

Error message:

TimeoutError: Navigation timeout of 30000 ms exceeded
    at LifecycleWatcher.js:100:111
    at Frame.goto (Page.js:476:53)
    at scrapeAll (main.js:13:18)

You’re spawning too many Chrome instances without cleaning them up properly. Add --no-sandbox --disable-dev-shm-usage flags when you launch the browser - fixed similar memory leaks for me. Also, use one page instead of creating new ones each time. Just navigate to about:blank between scrapes to clear resources.

The problem is memory leaks from connecting/disconnecting to the same browser instance - they pile up over time. I hit this same issue scraping large batches of URLs. My fix was restarting the browser every 50-100 iterations instead of keeping one alive for thousands of pages. Chrome actually cleans up all its processes and memory when you do this. Just track your iteration count and call mainBrowser.close() then puppeteer.launch() at regular intervals. The restart overhead is tiny compared to the performance hit you’re seeing. This killed my timeout errors and kept memory usage steady through long scraping runs.

You’re encountering zombie processes because browser.disconnect() doesn’t terminate the browser; it merely cuts the connection. Your main browser continues to spawn new processes for each page but doesn’t clean them up upon disconnection. I faced a similar issue while scraping large datasets. I resolved it by invoking await mainBrowser.close() within my loop every few hundred iterations and launching a fresh browser afterward, which effectively forces Chrome to clean up its processes. Alternatively, you can avoid the connect/disconnect pattern entirely and utilize mainBrowser.newPage() for each site, closing the page afterward. This approach is much cleaner and prevents process buildup, as Chrome’s memory management struggles with numerous orphaned processes.

This topic was automatically closed 4 days after the last reply. New replies are no longer allowed.