- __init__() function
- *args and **kwargs
- Aliases
- and operator
- argparse
- Arrays
- asyncio
- Booleans
- Break statement
- Bytes
- Classes
- Closure
- Code blocks
- Comments
- Conditional statements
- Console
- Context manager
- Data class
- Data structures
- Data types
- Data visualization
- datetime module
- Decorator
- Dictionaries
- Dictionary comprehension
- Django
- Docstrings
- Dunder methods
- Encapsulation
- enum
- enumerate() function
- Equality operator
- Error handling
- Exception handling
- False
- File handling
- Filter()
- Flask framework
- Floats
- Floor division
- For loops
- Formatted strings
- Functions
- Generator
- Globals()
- Greater than operator
- Greater than or equal to operator
- If statement
- in operator
- Indices
- Inequality operator
- Inheritance
- Integers
- Iterator
- JSON
- Lambda function
- len() Function
- Less than operator
- Less than or equal to operator
- List append() method
- List comprehension
- List count()
- List insert() method
- List pop() method
- List reverse() method
- List sort() method
- Lists
- Logging
- map() function
- Match statement
- Math module
- Merge sort
- Min()
- Modules
- Modulo operator
- Multiline comment
- Multiprocessing
- Multithreading
- None
- not operator
- NumPy library
- OOP
- Optional arguments
- or operator
- Override method
- Package manager (pip)
- Packages
- Pandas library
- Parameters
- pathlib module
- Pickle
- Polymorphism
- print() function
- Property()
- Protocol
- Random module
- range() function
- Raw strings
- Recursion
- Reduce()
- Regular expressions
- requests Library
- return statement
- round() function
- Script
- Set comprehension
- Sets
- SQLite
- String decode()
- String find()
- String join() method
- String replace() method
- String split() method
- String strip()
- Strings
- Ternary operator
- time.sleep() function
- True
- try...except statement
- Tuples
- Type casting
- Type hints
- uuid module
- Variables
- Virtual environment
- What is Python?
- While loops
- yield
- Zip function
PYTHON
Python asyncio Module: Syntax, Usage, and Examples
The asyncio module lets you run asynchronous code in Python, so your program can handle many tasks without blocking on slow operations. It’s especially useful for network requests, real-time apps, and other I/O-heavy work.
How to Use the asyncio module in Python
The module is built around three core ideas:
Learn Python on Mimo
- Coroutines: functions defined with
async def - Awaiting: pausing a coroutine with
awaituntil something finishes - Event loop: the engine that schedules tasks and runs them
Here’s the smallest example that runs an async function:
Python
import asyncio
asyncdefsay_hi():
print("Hi from async code!")
asyncio.run(say_hi())
Basic coroutine syntax
A coroutine is just a function that uses async def. Inside it, you can use await when you call other async functions.
Python
import asyncio
asyncdeffetch_profile():
await asyncio.sleep(1)
return {"name":"Mina","status":"online"}
asyncdefmain():
profile =await fetch_profile()
print(profile)
asyncio.run(main())
asyncio.sleep() is the async version of time.sleep(). The difference is huge: time.sleep() blocks the whole program, while asyncio.sleep() gives control back to the event loop so other tasks can run.
Running multiple tasks at once
To run coroutines concurrently, create tasks and wait for them together.
Python
import asyncio
asyncdefdownload_file(name, seconds):
print(f"Starting {name}")
await asyncio.sleep(seconds)
print(f"Finished {name}")
asyncdefmain():
task1 = asyncio.create_task(download_file("report.pdf",2))
task2 = asyncio.create_task(download_file("photo.png",1))
await task1
await task2
asyncio.run(main())
This is already better than running them one by one. Both tasks start, and the faster one finishes first.
Using gather() for cleaner concurrency
asyncio.gather() runs many coroutines concurrently and collects the results.
Python
import asyncio
asyncdefget_score(player):
await asyncio.sleep(1)
returnf"{player}: 100"
asyncdefmain():
results =await asyncio.gather(
get_score("Amina"),
get_score("Kai"),
get_score("Noah")
)
print(results)
asyncio.run(main())
When to Use the asyncio module in Python
Async code shines when your program spends time waiting. Think “waiting for the outside world”.
1) Making lots of network requests
Calling APIs and loading data from the internet can be slow. With async code, you can start many requests and process them as results arrive.
That’s perfect for:
- web scraping (responsibly)
- fetching user profiles from a service
- checking multiple endpoints
2) Building real-time apps
Async fits naturally in apps that stay “alive” and react to events.
Examples include:
- chat servers
- multiplayer game logic
- real-time dashboards
- bots that listen for messages
3) Handling many connections at the same time
If a server needs to handle hundreds or thousands of clients, blocking code becomes a problem quickly. Async makes it possible to keep things responsive even under load.
4) Running background I/O while doing other work
A program can continue running while waiting for:
- file reads
- database operations (through async libraries)
- incoming messages
- sensor updates
Examples of the asyncio module in Python
Below are three common patterns that show how async code behaves in practice.
Example 1: A simple timer that doesn’t block
Python
import asyncio
asyncdeftick():
for iinrange(3):
print(f"Tick {i + 1}")
await asyncio.sleep(1)
asyncio.run(tick())
This prints one tick per second, but it still leaves room for other async tasks to run.
Example 2: Running several “slow” tasks together
Let’s simulate multiple slow operations, like downloading data from different services.
Python
import asyncio
asyncdeffetch_data(source, seconds):
print(f"Fetching from {source}...")
await asyncio.sleep(seconds)
returnf"Data from {source}"
asyncdefmain():
results =await asyncio.gather(
fetch_data("Service A",2),
fetch_data("Service B",1),
fetch_data("Service C",3)
)
for itemin results:
print(item)
asyncio.run(main())
Even though one task takes 3 seconds, the total time is close to 3 seconds, not 6. That’s the main win.
Example 3: A repeating task using an infinite loop
Some apps need to keep checking for updates.
Python
import asyncio
asyncdefmonitor_status():
whileTrue:
print("Checking status...")
await asyncio.sleep(2)
asyncdefmain():
task = asyncio.create_task(monitor_status())
await asyncio.sleep(6)
task.cancel()
print("Stopped monitoring.")
asyncio.run(main())
This shows how a background task can run repeatedly until you stop it.
Learn More About the asyncio module in Python
Once you get past the basics, a few concepts come up again and again.
Await vs create_task()
await means “pause until this finishes”.
create_task() means “start this now, but don’t wait yet”.
Compare the two approaches.
Waiting one by one
Python
import asyncio
asyncdefjob(name):
await asyncio.sleep(1)
return name
asyncdefmain():
a =await job("A")
b =await job("B")
print(a, b)
asyncio.run(main())
This runs job A, then job B.
Running both at the same time
Python
import asyncio
asyncdefjob(name):
await asyncio.sleep(1)
return name
asyncdefmain():
task_a = asyncio.create_task(job("A"))
task_b = asyncio.create_task(job("B"))
results =await asyncio.gather(task_a, task_b)
print(results)
asyncio.run(main())
This runs them concurrently.
The event loop in plain language
The event loop is like a very organized manager.
- It starts tasks
- pauses tasks that are waiting
- resumes tasks when they’re ready
- keeps the program moving
You usually don’t manage the loop directly in beginner code because asyncio.run() does it for you.
Common mistakes with async code
A few things trip people up early.
Mistake 1: Forgetting to await a coroutine
This creates a coroutine object but doesn’t run it.
Python
import asyncio
asyncdefgreet():
print("Hello!")
asyncdefmain():
greet()# Missing await
asyncio.run(main())
Fix:
Python
import asyncio
asyncdefgreet():
print("Hello!")
asyncdefmain():
await greet()
asyncio.run(main())
Mistake 2: Using blocking code inside async functions
Calling time.sleep() inside a coroutine blocks the event loop.
Bad:
Python
import asyncio
import time
asyncdefslow():
time.sleep(2)
print("Done")
asyncio.run(slow())
Better:
Python
import asyncio
asyncdefslow():
await asyncio.sleep(2)
print("Done")
asyncio.run(slow())
Handling errors in async tasks
If multiple tasks run at once, one might fail. asyncio.gather() can raise an exception when that happens.
Python
import asyncio
asyncdefrisky_job():
await asyncio.sleep(1)
raise ValueError("Something went wrong")
asyncdefsafe_job():
await asyncio.sleep(1)
return"All good"
asyncdefmain():
try:
results =await asyncio.gather(risky_job(), safe_job())
print(results)
except ValueErroras error:
print("Caught error:", error)
asyncio.run(main())
In real apps, logging these errors matters, especially when tasks run in the background.
Timeouts with wait_for()
If you don’t want to wait forever, wrap a coroutine in asyncio.wait_for().
Python
import asyncio
asyncdefslow_request():
await asyncio.sleep(5)
return"Response"
asyncdefmain():
try:
result =await asyncio.wait_for(slow_request(), timeout=2)
print(result)
except asyncio.TimeoutError:
print("Request timed out")
asyncio.run(main())
Timeouts are common in network code.
asyncio vs threading
Both can help with concurrency, but they shine in different situations.
- Async is great for I/O tasks like network calls and waiting for input.
- Threads can help when you need blocking libraries or background work that doesn’t support async.
CPU-heavy tasks, like video encoding or large math operations, usually need multiprocessing or optimized libraries, because async won’t make CPU work faster.
Summary
The asyncio module helps you write non-blocking code in Python using async def, await, and an event loop. Use it for I/O-heavy tasks like network requests, real-time applications, and handling many connections at once. Once you understand coroutines, tasks, and tools like gather() and wait_for(), async programming starts to feel natural and can seriously speed up your workflow without adding messy complexity.
Join 35M+ people learning for free on Mimo
4.8 out of 5 across 1M+ reviews
Check us out on Apple AppStore, Google Play Store, and Trustpilot