Advertisement
If you’ve worked with Python long enough, you’ve probably heard the word coroutines pop up—maybe during a conversation about asyncio or while trying to understand what's really happening behind an await. Coroutines may sound a little intimidating at first, but they're just a smarter way to write code that doesn't waste time waiting. Instead of freezing everything while a function finishes, coroutines let other parts of your program get stuff done in the meantime. That's the simple version, but let's go a bit deeper.
You know how a regular function runs from top to bottom, and then it's done? A coroutine can pause itself in the middle, hand control back to something else, and then pick up right where it left off. That's the main difference.
Coroutines start out looking like generators. They use the yield keyword—or, more commonly, in newer Python code, async def and await. When you see async def, you're defining a coroutine. And when you use await, you're telling Python to pause that coroutine until the thing you're waiting for finishes—usually something like a file read, an API call, or a timer.
This is great for tasks that don’t need to sit there doing nothing. Instead of blocking your whole program, coroutines let Python switch to something else until the task is ready to continue. It’s like calling someone, leaving a voicemail, and moving on with your day while waiting for them to call back.
Let’s say you're writing a program that fetches data from three different websites. If you write it the usual way, each call waits until the previous one is done. That means if each takes 2 seconds, your whole script takes 6 seconds.
Now imagine if you used coroutines. Each request gets sent out, and while waiting for a response, your code doesn’t just sit there. It moves on to the next task. When the first response comes back, the coroutine picks up again and finishes the job.
You just shaved off a big chunk of wait time—and your script feels faster, smoother, and more efficient. This is especially useful for web scraping, chatbots, file handling, and anything else that needs to wait but shouldn’t waste time doing it.
Python coroutines aren’t magic. They rely on an event loop—a simple engine that checks on tasks, sees if they’re ready, and keeps everything running without blocking.
When you define a coroutine using async def, you’re creating something that won’t run until you await it or pass it to the event loop. You can think of it like prepping a to-do list but not actually checking anything off until it’s time.
Here’s what happens in practice:
It’s a bit like putting a bookmark in a book while you go do something else, then picking up right where you stopped—no need to start over.
Let’s walk through how to write and use coroutines in Python, one step at a time.
To start, define a coroutine using async def instead of the usual def. For example:
python
async def greet():
print("Hello")
This hasn't run the code inside yet. Calling greet() returns a coroutine object. To actually execute it, you need to wait for it.
That’s where asyncio.run() comes in. It sets up the event loop, runs your coroutine, and then handles the cleanup.
python
import asyncio
async def greet():
print("Hello")
asyncio.run(greet())
Now you’ll see “Hello” printed. Behind the scenes, Python is handling everything needed to run this asynchronous code.
Let's add a bit more to it—maybe a pause to simulate a delay, like waiting for a network response or a file to load. You can do that by awaiting asyncio sleep().
python
import asyncio
async def greet():
print("Hi there")
await asyncio.sleep(2)
print("Thanks for waiting")
This will print “Hi there,” then pause for two seconds before printing “Thanks for waiting.” The important thing is that it doesn’t block the rest of your program while waiting. The event loop can keep doing other things.
Now comes the part that makes coroutines really useful: running several of them at the same time. Let's say you want to greet three people but without waiting for one to finish before starting the next.
python
import asyncio
async def greet(name):
print(f"Hi {name}")
await asyncio.sleep(1)
print(f"Bye {name}")
async def main():
await asyncio.gather(
greet("Alice"),
greet("Bob"),
greet("Charlie")
)
asyncio.run(main())
Each greet() coroutine runs on its timeline, but they share the same event loop. Even though each one pauses for a second, they all do it at the same time. So, instead of taking three seconds, the whole thing takes just a bit over one. Python quietly switches between them in the background, giving the feel of things happening all at once—even though it's all happening in a single thread.
Coroutines let Python do more by waiting for less. Instead of blocking your program on slow tasks, you get to pause and switch to something else—without threads or complicated logic. It all runs through a clean event loop, using simple syntax like async def and await. So if you're dealing with anything that might take time—downloads, database queries, timers—coroutines are worth learning. They don't just make your code faster; they make it feel cleaner and more modern. Try writing a few on your own, and you'll start to see where they fit. It's not about making everything async but knowing when it helps. And once you get the hang of it, there’s no going back.
Advertisement
Can AI-generated games change how we play and build games? Explore how automation is transforming development, creativity, and player expectations in gaming
Struggling with synth patches or FX chains? Learn how ChatGPT can guide your sound design process inside any DAW, from beginner to pro level
Think My AI is just a fun add-on? Here's why Snapchat’s chatbot quietly helps with daily planning, quick answers, creativity, and more—right inside your chat feed
Learn the 10 best AI podcasts to follow in 2025 and stay updated with the latest trends, innovations, and expert insights.
Case study: How AI-driven SOC tech reduced alert fatigue, false positives, and response time while improving team performance
Explore the various ways to access ChatGPT on your mobile, desktop, and through third-party integrations. Learn how to use this powerful tool no matter where you are or what device you’re using
Know how AI-powered advertising enhances personalized ads, improving engagement, ROI, and user experience in the digital world
Learn how to create the perfect headshot using LightX Photo Editor. This step-by-step guide covers lighting, background edits, retouching, and exporting for a professional finish
Curious about Python coroutines? Learn how they can improve your code efficiency by pausing tasks and running multiple functions concurrently without blocking
Wondering how ChatGPT can help with your novel? Explore how it can assist you in character creation, plot development, dialogue writing, and organizing your notes into a cohesive story
Knime enhances its analytics suite with new AI governance tools for secure, transparent, and responsible data-driven decisions
Pinecone unveils a serverless vector database on Azure and GCP, delivering native infrastructure for scalable AI applications