Async Generators: `yield` in an `async` World

Async generators let you write I/O-bound data streams with the elegance of yield. An async def function with yield produces values one at a time, pausing for I/O without blocking. This is ideal for streaming data from a database.
Why it exists
Before async generators, creating an asynchronous data producer was verbose. You had to write a full class implementing the aiter and anext methods just to make it work with async for, which was cumbersome for simple streaming logic.
The mental model
Think of an async generator as a regular Python generator that can await. It's a function that produces a sequence of values over time, but it can pause for I/O operations (like a network request or database query) between yields without blocking the entire program's event loop.
How it works
You define a function with async def and use one or more yield expressions inside it. Calling this function doesn't run it; it immediately returns an asynchronous generator object. This object implements the asynchronous iteration protocol, allowing it to be used in an async for loop. Each time the loop requests the next item, the generator's code runs until it hits a yield, provides the value, and then pauses its state until the next item is requested.
When to use it
Use async generators when you need to produce a sequence of items, and the production of each item involves an I/O-bound operation that needs to be awaited. This is perfect for streaming rows from a database cursor, reading a large file in chunks from a remote server, or processing data from a WebSocket connection as it arrives.
When not to use it
If your data generation is purely CPU-bound and involves no await calls, a regular generator is simpler and more efficient. Also, if you need to return a final value from the function after iteration is complete, an async generator is not the right tool, as a non-empty return statement is a SyntaxError.
One canonical example
Instead of a complex class, you can write a simple function to stream numbers with a delay. async def ticker(delay, to): for i in range(to): yield i; await asyncio.sleep(delay). This is consumed in another async function with async for num in ticker(1, 5): print(num). This is significantly cleaner and, according to the PEP, about twice as fast as the manual class-based implementation.
Interview question
For which scenario is an async generator the most suitable Python construct?
- a.Implementing a function that needs to return a final aggregated result after yielding intermediate values.
- b.Executing multiple independent, CPU-intensive tasks concurrently to improve overall program throughput.
- c.Generating a sequence of values where each value's creation involves an I/O operation that must be awaited.Correct
- d.Producing a sequence of items that are computed entirely in memory without any external dependencies.
Why? this is the answer
The card states async generators are ideal "when you need to produce a sequence of items, and the production of each item involves an I/O-bound operation that needs to be awaited." Option A is incorrect because async generators do not support returning a final value after yielding, and C describes a regular generator's use case.
Just read this? Test yourself on what you have been reading.
Read the original → peps.python.org
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on python — each one lists the topics its interview covers.
See open roles