NovFora Dev

Unexpected memory leak in Python asyncio — help!

Taylor Davis

Taylor Davis

4 months ago

I have an asyncio service that allocates ~50MB/hour under steady load. I've ruled out circular references, large task queues, and file descriptor leaks. Could this be related to loop.create_task creating detached coroutines that never resolve?

Taylor Davis

Taylor Davis

4 months ago

This is almost certainly one of three common culprits:

1. Unclosed Tasks. The most frequent cause by far. If you're creating tasks via asyncio.create_task(coro()) and they keep running or never complete, the task object stays alive forever with its entire coroutine context. A loop that spawns a new task every request without awaiting it will leak memory linearly with request count.

2. Event Loop Task Reference. If you're passing loop=loop to callbacks from Python 3.7+, those references can create circularities the garbage collector doesn't always break immediately. In modern asyncio, let the loop be implicit — don't pass it around.

3. Caching coroutines/futures. If your app has a registry of ongoing work or caches results keyed by request IDs that never get evicted, you have a leak. Check asyncio.all_tasks(loop) periodically in development to

Owen Martin

Owen Martin

4 months ago

Found this too. Looks like it's related to task objects being kept alive after cancellation.

Owen Martin

Owen Martin

4 months ago

Check whether you're creating tasks without awaiting them or storing them in a list that never clears

Avery Rodriguez

Avery Rodriguez

4 months ago

Obvious you've got a circular reference somewhere and didn't think about gc.collect() or weakrefs. The logs will show you exactly where — assuming you actually read them this time. Search the asyncio issues on GitHub for "memory leak" and scroll down past the top posts to

Avery Rodriguez

Avery Rodriguez

4 months ago

Read the issue tracker and you'll see this was resolved three years ago. The bug was a reference cycle held by task callbacks in older versions of asyncio, which got fixed with weakref_callback in 3.10+. If you're running anything older than that, update your

Join the conversation to leave a reply.

Sign in to reply

Related topics