Repository navigation
[Bug]: Object leak in Tracing #2977
Description
Activity
-
I ran a test with and without tracing across 30 iterations.
-
Both scenarios show a small memory increase in the first few iterations (stabilizing after ~39 MB).
-
No continuous growth is observed after stabilization.
-
This suggests normal caching behavior rather than a memory leak.
Here’s a comparison chart for reference:
You can reproduce with this script:
import psutil import os from playwright.sync_api import sync_playwright def memory_usage(): process = psutil.Process(os.getpid()) return process.memory_info().rss / (1024 * 1024) # MB def run_test(use_tracing=False, iterations=30): with sync_playwright() as p: for i in range(1, iterations + 1): browser = p.chromium.launch() context = browser.new_context() if use_tracing: context.tracing.start(screenshots=True, snapshots=True, sources=True) page = context.new_page() page.goto("https://example.com") if use_tracing: context.tracing.stop(path=f"trace_{i}.zip") browser.close() print(f"[after iteration {i}] Memory usage: {memory_usage():.2f} MB") print("=== Running without tracing ===") run_test(use_tracing=False) print("\n=== Running with tracing ===") run_test(use_tracing=True)
-
Tested your code and seems that leaking behavior is only reproducible with
async_playwright, so i modified your code to async and then the leak can be observed.Things I changed:
- Added gc object printing so that the growth would be seen
- Changed to
async_playwright - Added more
gotoactions, seems to speed up the object creation
Results after just 30 loops
Modified code:
import asyncio import psutil import os import gc from collections import Counter from playwright.async_api import async_playwright def memory_usage(): process = psutil.Process(os.getpid()) objects = gc.get_objects() type_counter = Counter(type(obj) for obj in objects) print("Top 15 object types by count:") for obj_type, count in type_counter.most_common(15): print(f"{count:>8} objects | {obj_type}") return process.memory_info().rss / (1024 * 1024) # MB async def run_test(use_tracing=False, iterations=30): async with async_playwright() as p: for i in range(1, iterations + 1): browser = await p.chromium.launch() context = await browser.new_context() if use_tracing: await context.tracing.start(screenshots=True, snapshots=True, sources=True) page = await context.new_page() for _ in range(100): await page.goto("https://playwright.dev/") if use_tracing: await context.tracing.stop(path=f"trace_{i}.zip") await browser.close() print(f"[after iteration {i}] Memory usage: {memory_usage():.2f} MB") if __name__ == "__main__": asyncio.run(run_test(True))Hey, thanks a lot for taking the time to dig into this 🙏. I see you modified the script to use async_playwright and could reproduce the leak there. In my case, I was originally running with sync_playwright, and I didn’t hit the leak.
Since you’ve now confirmed the async version behaves differently, would you prefer that we continue debugging on the async side, or stick with the sync version (which doesn’t show the issue on my end)? Just want to be sure we’re focusing on whichever one you want to use going forward.
I think this issue will be related to how callbacks are handled because after further investigation I noticed that
playwright._impl.ProtocolCallbackobject keep growing which hold the traceback objects so it will probably be issue of not cleaning up properly. Additionally noticed that those object seem to be left uncollected everywhere wheresend_no_replyfunction is used. Will try to investigate further- added 4 commits that reference this issue
on Sep 23, 2025 - added a commit that references this issue
on Oct 7, 2025
Version
1.55.0
Steps to reproduce
Example steps (replace with your own):
if tracing is turned off then the memory stays stable and there are no additional objects created after each loop
Expected behavior
Object count and memory should return to initial after tracing is stopped
Actual behavior
When tracing is stopped callback objects keep accumulating
Additional context
No response
Environment