---
title: 'Python AsyncIO Explained in 9 Minutes'
source: 'https://youtube.com/watch?v=q_yk3oV14hE'
video_id: 'q_yk3oV14hE'
date: 2026-06-16
duration_sec: 0
---

# Python AsyncIO Explained in 9 Minutes

> Source: [Python AsyncIO Explained in 9 Minutes](https://youtube.com/watch?v=q_yk3oV14hE)

## Summary

This video provides a quick introduction to asynchronous programming in Python using AsyncIO. It explains how to create coroutines, use the event loop, and manage concurrent tasks with `await`, `gather`, and `wait` functions.

### Key Points

- **Introduction to AsyncIO** [0:00] — The video aims to cover asynchronous programming in Python with AsyncIO as quickly as possible, without deep diving into details.
- **Concurrent Programming in Python** [0:42] — Three major ways: asynchronous programming, multi-threading, and multiprocessing. Multiprocessing for CPU-bound tasks, multi-threading for I/O-bound tasks without manual control, and async for I/O-bound tasks with manual control.
- **Creating a Coroutine** [2:03] — A coroutine is defined with `async def` and can be suspended/resumed. Example: `async def io_task(name, delay, iterations)`.
- **Awaiting AsyncIO Sleep** [2:32] — `await asyncio.sleep(delay)` yields control back to the event loop, allowing other coroutines to run during idle time.
- **Using asyncio.gather for Concurrency** [3:39] — `asyncio.gather` runs multiple coroutines concurrently. Example: `asyncio.gather(task_a, task_b, task_c)` completes in ~4.5 seconds vs 11 seconds serially.
- **Importance of Await** [5:15] — Using `time.sleep` instead of `await asyncio.sleep` blocks the thread and prevents concurrency. `await` is essential to return control to the event loop.
- **Background Tasks with create_task** [6:00] — `asyncio.create_task` schedules a coroutine to run in the background. Example: `task = asyncio.create_task(background_task())` allows other code to run before awaiting the task.
- **Using asyncio.wait with Conditions** [6:55] — `asyncio.wait` can specify return conditions like `FIRST_COMPLETED`. Returns sets of done and pending tasks. Example: `done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)`.
- **Timeout with asyncio.wait_for** [8:17] — `asyncio.wait_for` adds a timeout. If exceeded, raises `asyncio.TimeoutError`. Example: `await asyncio.wait_for(long_operation(), timeout=2)`.

### Conclusion

AsyncIO enables efficient concurrency for I/O-bound tasks using a single thread and an event loop. Key functions like `gather`, `wait`, and `wait_for` provide flexible control over coroutine execution.

## Transcript

Today we're going to learn about
asynchronous programming in Python with
Async IO as quickly as possible. So let
us get right into it.
[Music]
>> All right, so as always when it comes to
these tutorials where I try to cover
something as quickly as possible, this
is not going to be a deep dive. We're
not going to go into a lot of details. I
wouldn't even call it a crash course.
It's more like me giving you a very very
quick introduction into the topic and
then you can continue to study it on
your own or if you want to you can leave
me a comment in the comment section down
below and let me know that you're
interested in a more detailed course so
maybe I can do that as well on my
channel but asynchronous programming
belongs to the category of concurrent
programming in Python and there are
three major ways to do concurrent
programming in Python one is
asynchronous programming another one is
multi-threading and another one is
multipprocessing for the last two I
already have two videos on my channel
similar to this one where I cover them
as quickly as possible. So you can take
a look at them if you want to. And today
we're going to talk about asynchronous
programming. Now in a nutshell, you want
to use multipprocessing when you have a
lot of CPUbound tasks that you want to
parallelize. So heavy computations that
you want to do simultaneously on
multiple CPU cores. You actually want to
have multiple processes. Uh you don't
want to be limited by the global
interpreter log. Multi-threading is a
little bit more I wouldn't necessarily
say exotic, but it's a bit odd in Python
because you have the global interpreter
lock and you don't have real
multi-threading unless you release the
global interpreter lock. But
essentially, you want to use it when you
don't want to manually handle the
control. So you don't want to manually
switch between the different threads and
you also maybe have to work with
something that doesn't support
asynchronous programming. But I want I
don't want to talk about this too much.
I want to focus on asynchronous
programming today. uh which is the topic
of this video. So let us go into our
coding directory. In my case, I'm going
to navigate to the tutorial directory.
And here now I'm going to create a file
called main.py. Now I'm going to start
by importing async io and creating a
so-called co- routine. So a co- routine
is basically a program component that
can be suspended and resumed. So we can
pause this. We can continue with this.
And we define it by saying async defaf
and then the name IO task. So an
asynchronous function essentially. In
this case, this one takes name, delay,
and number of iterations as a parameter.
Then we have a couple of iterations in
this loop here. And we just print the
task name and the current iteration just
so we can keep track of what is actually
happening. And the key thing here is
awaiting the async io. Call. So this is
just a placeholder. You could have
anything here awaiting something that is
asynchronous. So this could be also
waiting for a response from a server.
Basically just any downtime that can be
used in this single thread that we're
running. Now asynchronous programming
runs in a so-called event loop. We have
one thread so we don't have any
concurrent I mean we do have concurrency
but we don't have any parallel
execution. We don't have multiple
threads. We don't have multiple
processes. We have one thread and the
event loop basically switches between
the co- routines. So in this case, what
we're saying here is we're saying print
a statement and then give back control
yield back to the event loop and allow
it to do something else while we're
doing this. So we're basically saying
sleep for whatever we pass as delay
seconds and then go back here. So every
iteration each iteration here is going
to call this await async io sleep which
means we're giving back control to the
event loop and the event loop can then
determine which of the other co-
routines are capable of resuming. So we
can see that this works by defining an
asynchronous main function. What we do
here is we measure the time of the
executions. We have one time here an
async io gather call. So we're calling
the gather function and we're passing
here three tasks called A, B and C with
different delays but the same number of
iterations. And these are going to be
executed asynchronously. So concurrently
as three co- routines which basically
means when A is sleeping we can do B.
When A and B are sleeping we can do C
and so on. So we can switch back and
forth because we have this downtime this
idle time. Uh in addition to that down
below here we have three separate await
statements. So we await three tasks in a
row. So this is serially. This is not
concurrently. We're not using the gather
function. And this basically means task
A has to be executed. Then task B has to
be executed. Task C has to be executed.
And then we're done. Now of course here
I also need to import time and also of
course we need to run the main function
here. We do that by starting an event
loop by creating an event loop with
async io run. So we do async io run and
we pass main. But we don't pass main as
a function. So as a reference to the
function, we actually call main and we
do that in async.io run. So we're
actually using parenthesis in here. So
when I run this now, you can see we have
a, b, and c being executed concurrently.
So this happens um yeah at the same time
basically 4.5 seconds. Whereas if I do
that separately, we can see that we have
first a then b then c and this is going
to take much longer 11 seconds. Now,
this also happens if we're not awaiting.
Await is the keyword that returns
control back to the event loop. So, if I
instead cause some downtime here with
time. Which is perfectly fine. I can do
that. If I say time.sleep delay instead
of async io sleep delay, this doesn't
work anymore because now I'm never
returning control back to the event
loop. I now basically say there is some
downtime. But since we're not using
multi-threading here, what is actually
happening is we're just waiting. we're
blocking uh the threat. So we're just
waiting for this to finish before we can
move on. So if you actually want to give
control back to the event loop, you have
to use await. And in this case, you
would have to use async io. Another
thing that we can do is we can run tasks
in the background and we can return
them, save them into a variable and then
await them at some point later in the
function. So here for example, I have
this background task which prints
running then waits for 5 seconds then
prints finishing. And what I can do here
is I can do async.io.create task with
background task being called in here. Uh
this returns then the task instance.
Whatever happens afterwards is executed
immediately. So this print statement for
example. But then I can also await the
task and I can say okay don't continue
until this is done and then print the
final statement. And of course
everything that happens after async io
run also has to wait for all of this to
finish. So if I run this you can see
continuing immediately um even before
running is being printed and then only
when this background task is finished
because we're awaiting it here only then
do we get but for this we need to wait
and this waits two what can also be
interesting is using the wait function
in this case here we have again a very
simple setup we have two co- routines
print statement waiting time print
statement return value here with 2
seconds here with 5 seconds and then we
have them as two tasks and Then we use
the weight function not the gather
function. This allows us to specify a
return condition. So in this case we do
done and pending await async io.we and
then we specify here return when async
io first completed. What this basically
means is that this whole thing is going
to return. So we're going to stop
waiting when one of them returns. So
when the first one returns we're going
to continue with the code and this is
going to return two things. It's going
to return the list of the tasks that are
finished. So that are done and the list
of the tasks that are not finished yet.
So we can also print all of that after
this is being awaited. We can print the
finished tasks and the pending tasks.
And then in the end we can also do
another await asai await pending to wait
for the remaining tasks. So let's run
this now. You can see one start two
start then one finishes one end. You can
see the finished tasks are uh result is
equal to one done and then we have the
pending tasks which doesn't have a
result yet. So we have a future and at
some point then this also finishes and
we get to end. Now if you don't want to
wait indefinitely, you can also use the
wait for function. This allows us to
specify a timeout. In this case we have
a long operation taking 5 seconds and we
only allow for 2 seconds by using wait
four. In the case that these two seconds
are surpassed we get a timeout error. we
can catch that and handle it. Uh but in
this case, we're just going to print
took too long. So if I run this, you're
going to see one, two, took too long
because this takes 5 seconds and this
takes 2 seconds. Of course, this only
works with a wait because we need to
pass control back to the event loop. Uh
it doesn't work if I use time. Because
then it's going to block the threat. And
that's basically it. There's of course
much more to cover. Manual stuff you can
do with the event loop, task groups,
shielding, and so on. There's much more
to cover in general when it comes to
concurrency in Python. If you want to
have more detailed tutorials, let me
know in the comment section down below.
So, that's it for today's video. I hope
you enjoyed it and hope you learned
something. If so, let me know by hitting
a like button and leaving a comment in
the comment section down below. Also,
don't forget to check out the similar
videos I already have on multi-threading
and multipprocessing. And of course,
don't forget to subscribe to this
channel and hit the notification bell to
not miss a single future video for free.
Other than that, thank you much for
watching. See you in the next video and
bye.
