Skip to content

Page Pooling Causes High Memory Usage #2946

Closed

Description

@congche

Title:
High Memory Usage with PuppeteerSharp Page Pooling – Is Page Reuse Recommended for PDF Generation?

Body:
I'm using PuppeteerSharp in a .NET backend service to generate PDFs at scale. To improve throughput, I implemented a pool of 10 IPage objects and reuse them for each PDF generation request.
Here’s a simplified version of my pooling logic:

// Page pool initialization
for (int i = 0; i < 10; i++)
{
    var page = await browser.NewPageAsync();
    pagePool.Add(page);
}

// PDF generation
var page = await GetPageFromPool();
await page.SetContentAsync(html);
var pdf = await page.PdfDataAsync(options);
await ReturnPageToPool(page);

Issue:
Over time, I observe that memory usage on the server keeps increasing and does not decrease, even after many PDF generations.
The following screenshot (Linux, top command) shows multiple Chromium processes and sustained high memory consumption

Image

Questions:

Is pooling and reusing IPage objects a recommended practice in PuppeteerSharp for high-concurrency PDF generation?
Would it be more efficient and stable to create a new page for each request and dispose it immediately after use?
Are there any best practices or patterns for managing memory and resource cleanup in this scenario?
Any insights, recommendations, or real-world experiences would be greatly appreciated!

Thanks

Activity

  1. kblok commented on Aug 21, 2025

    @kblok
    Member

    Do you see an increase in memory in chromium or dotnet?

  2. congche commented on Aug 21, 2025

    @congche
    Author

    @kblok
    I’m seeing memory growth mainly in the Chromium processes (see screenshot), not in the .NET process.

    Even after resetting page content with await page.SetContentAsync("") after each PDF generation, metrics like JSHeapUsedSize from page.MetricsAsync() keep increasing for each pooled page.

  3. kblok commented on Aug 21, 2025

    @kblok
    Member

    @kblok I’m seeing memory growth mainly in the Chromium processes (see screenshot), not in the .NET process.

    Even after resetting page content with await page.SetContentAsync("") after each PDF generation, metrics like JSHeapUsedSize from page.MetricsAsync() keep increasing for each pooled page.

    So it's more the browser having a memory leak. Maybe you could try closing the page and opening a new one after each generation?

  4. congche commented on Aug 21, 2025

    @congche
    Author

    I’ve been thinking about two possible optimizations:

    1. Not pooling pages, but closing and recreating them after each generation.
    2. Periodically restarting the browser instance.

    I’ve noticed Playwright samples dispose pages after each use, but I’m not sure if this is the recommended best practice or if it could cause other issues.

    Would appreciate any further insights or references. Thanks again!

  5. locked and limited conversation to collaborators on Aug 21, 2025
  6. converted this issue into a discussion #2947 on Aug 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions