DEV Community

Brad Hankee
Brad Hankee

Posted on

Stop Waiting Around: Async & Await in Python Explained

Hey JavaScript… Python’s got async too!

So what exactly is async, and why should you care about it in Python?

Since Python has become the go-to language for AI, data, and backend services, understanding asynchronous programming is more important than ever. If you’re making calls to LLMs, APIs, or any external service, async gives you a powerful way to manage those operations without your program sitting idle and wasting time.

What Async Actually Is

Think of async as lightweight concurrency. It’s similar to threading or multiprocessing, but much simpler to write and more efficient in many cases.

When you define a function with:

async def my_function():
    ...

Enter fullscreen mode Exit fullscreen mode

you’re not just making a normal function. Technically, you’re creating a coroutine — a special kind of function that can be paused and resumed.

What Happens When You Call a Coroutine?

Here’s the gotcha: if you just call it, you don’t actually run it. You get back a coroutine object. To execute it, you need the await keyword:

result = await my_function()
Enter fullscreen mode Exit fullscreen mode

That await tells Python: “Pause here until the coroutine is done, then give me the result.”

So while the word “async” sounds non-blocking, the await line itself is blocking for that specific call.

Enter the Event Loop

The real magic comes from Python’s built-in event loop (provided by asyncio). The event loop is like a conductor for your coroutines. While one coroutine is waiting — say, for an API call — the loop can run another one in the meantime.

This gives you concurrency without the complexity of threads.

Running Multiple Coroutines

One of the coolest features is asyncio.gather(). With it, you can schedule multiple coroutines to run “at once” (really, managed by the event loop):

import asyncio

async def first_run():
    await asyncio.sleep(1)
    return "First done"

async def second_run():
    await asyncio.sleep(2)
    return "Second done"

async def third_run():
    await asyncio.sleep(1)
    return "Third done"

async def main():
    output = await asyncio.gather(
        first_run(),
        second_run(),
        third_run()
    )
    print(output)

asyncio.run(main())


Output:

['First done', 'Second done', 'Third done']
Enter fullscreen mode Exit fullscreen mode

Even though second_run() takes longer, the others don’t wait around — the event loop keeps everything moving efficiently.

Takeaway

async and await give Python developers an elegant way to write concurrent code. Whether you’re working with LLMs, APIs, or just want your app to be more responsive, it’s a tool worth learning.

So next time someone drops “coroutine” in your Slack thread, you’ll know what’s up. 😉

Top comments (0)