You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
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!
@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.
@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?
I’ve been thinking about two possible optimizations:
Not pooling pages, but closing and recreating them after each generation.
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!
Activity
kblok commentedon Aug 21, 2025
Do you see an increase in memory in chromium or dotnet?
congche commentedon Aug 21, 2025
@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.
kblok commentedon Aug 21, 2025
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?
congche commentedon Aug 21, 2025
I’ve been thinking about two possible optimizations:
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!