I think I know part of the answer. I tried to summarize my understanding of the differences, in order of importance, between asyncio tasks and goroutines:

1) Unlike under asyncio, one rarely needs to worry that their goroutine will block for too long. OTOH, memory sharing across goroutines is akin to memory sharing across threads rather than asyncio tasks since goroutine execution order guarantees are much weaker (even if the hardware has only a single core).

asyncio will only switch context on explicit await, yield and certain event loop methods, while Go runtime may switch on far more subtle triggers (such as certain function calls). So asyncio is perfectly cooperative, while goroutines are only mostly cooperative (and the roadmap suggests they will become even less cooperative over time).

A really tight loop (such as with numeric computation) could still block Go runtime (well, the thread it's running on). If it happens, it's going to have less of an impact than in python - unless it occurs in mutliple threads.

2) Goroutines are have off-the-shelf support for parallel computation, which would require a more sophisticated approach under asyncio.

Go runtime can run threads in parallel (if multiple cores are available), and so it's somewhat similar to running multiple asyncio event loops in a thread pool under a GIL-less python runtime, with a language-aware load balancer in front.

3) Go runtime will automatically handle blocking syscalls in a separate thread; this needs to be done explicitly under asyncio (e.g., using run_in_executor).

That said, in terms of memory cost, goroutines are very much like asyncio tasks rather than threads.

Answer from max on Stack Overflow
Top answer
1 of 2
12

I think I know part of the answer. I tried to summarize my understanding of the differences, in order of importance, between asyncio tasks and goroutines:

1) Unlike under asyncio, one rarely needs to worry that their goroutine will block for too long. OTOH, memory sharing across goroutines is akin to memory sharing across threads rather than asyncio tasks since goroutine execution order guarantees are much weaker (even if the hardware has only a single core).

asyncio will only switch context on explicit await, yield and certain event loop methods, while Go runtime may switch on far more subtle triggers (such as certain function calls). So asyncio is perfectly cooperative, while goroutines are only mostly cooperative (and the roadmap suggests they will become even less cooperative over time).

A really tight loop (such as with numeric computation) could still block Go runtime (well, the thread it's running on). If it happens, it's going to have less of an impact than in python - unless it occurs in mutliple threads.

2) Goroutines are have off-the-shelf support for parallel computation, which would require a more sophisticated approach under asyncio.

Go runtime can run threads in parallel (if multiple cores are available), and so it's somewhat similar to running multiple asyncio event loops in a thread pool under a GIL-less python runtime, with a language-aware load balancer in front.

3) Go runtime will automatically handle blocking syscalls in a separate thread; this needs to be done explicitly under asyncio (e.g., using run_in_executor).

That said, in terms of memory cost, goroutines are very much like asyncio tasks rather than threads.

2 of 2
1

I suppose you could think of it working that way underneath, sure. It's not really accurate, but, close enough.

But there is a big difference: in Go you can write straight line code, and all the I/O blocking is handled for you automatically. You can call Read, then Write, then Read, in simple straight line code. With Python asyncio, as I understand it, you need to queue up a function to handle the reads, rather than just calling Read.

🌐
Reddit
reddit.com › r/golang › go vs python async?
r/golang on Reddit: Go vs Python async?
October 29, 2017 -

For anyone who's tried both Go and Python async (ex uvloop + sanic, apistar, etc) for their webapp, what are the pros and cons of working in each language?

🌐
Hacker News
news.ycombinator.com › item
Goroutines and Async-Await are two very different takes on the same problem. In ... | Hacker News
May 7, 2019 - In C# or Python 3, each function is colored as either sync or async. You can quite easily call an async function from a sync context, but doing a blocking sync call from an async context is forbidden (although possible) · In Go there is no such distinction: you just write your functions in ...
🌐
YouTube
youtube.com › dev internals
1. Golang goroutines vs Python asyncio (part 1) - YouTube
In this first video we are going to explore concurrent programming with unique approach. First we will write our code with Golang concurrent programming tech...
Published   October 21, 2020
Views   169
🌐
PeerDH
peerdh.com › blogs › programming-insights › goroutines-vs-asyncio-performance-benchmarks
Goroutines Vs Asyncio Performance Benchmarks – peerdh.com
September 20, 2024 - Goroutines: Can handle thousands of concurrent requests with minimal overhead. Asyncio: Also performs well but may struggle with very high concurrency due to Python's Global Interpreter Lock (GIL).
🌐
Quora
quora.com › Are-Python-coroutines-and-Go-goroutines-the-same
Are Python coroutines and Go goroutines the same? - Quora
The Python coroutines operate within an async/await programming model. Go goroutines use a synchronous channel based programming model. Python coroutines are still limited in concurrency by the Global interpreter lock.
🌐
Python.org
discuss.python.org › python help
Have there some like Goroutines in Python 3.13 or maybe 3.14 - Python Help - Discussions on Python.org
May 15, 2024 - I’m referring to A Tour of Go and I’m not saying that we must use the go keyword but should be fine to have something to manage the multithreading automatically, but… which should be the approach?
🌐
DEV Community
dev.to › bobfang1992_0529 › async-programming-faster-but-how-much-faster-3hl1
Async Programming: faster, but how much faster? - DEV Community
December 14, 2021 - TL;DR: Python asyncio is about 3.5 times faster than threading. Golang is very performant and has better scalability.
Find elsewhere
🌐
LinkedIn
linkedin.com › pulse › mastering-concurrency-goroutines-python-coroutines-asgi-fadi-zaboura
Mastering Concurrency: Goroutines, Python Coroutines, ASGI vs. WASGI, ASGI Server Workers, and Demystifying Concurrency, Threads, and Parallelism
August 12, 2023 - In both Goroutines and Python Coroutines, handling multiple asynchronous tasks efficiently is vital for performance. The examples above showcase how to initiate and manage multiple tasks simultaneously using concurrency primitives like channels and asyncio.Queue.
🌐
PeerDH
peerdh.com › blogs › programming-insights › comparing-gos-goroutines-and-pythons-asyncio
Comparing Go's Goroutines And Python's Asyncio – peerdh.com
October 5, 2024 - If you are building a high-performance server that needs to handle many simultaneous connections, Go's goroutines may be the better choice. They provide a straightforward way to manage concurrency with minimal overhead.
🌐
Pythonade
pythonade.com › pythonvsgo.html
Pythonade - Concurrency Face-Off: Python vs Go
This allows Go programs to run thousands or even millions of concurrent goroutines with minimal overhead. By contrast, Python's coroutines require more explicit syntax and management: import asyncio async def say_hello(): print("Hello, world!") async def main(): # Create a coroutine await say_hello() print("Done") # Run the event loop asyncio.run(main())
🌐
Johal AI Hub
johal.in › go-concurrency-python-asyncio-trio-alternatives-comparison-2025
Go Concurrency Python asyncio: Trio Alternatives Comparison 2025
November 22, 2025 - Trio's nurseries prevent zombie tasks, unlike asyncio's manual cancellation. Go goroutines deliver 5-10x higher throughput for I/O-bound workloads due to preemptive M:N scheduling, revolutionizing 2025 cloud-native apps.
🌐
DEV Community
dev.to › swizzard › is-pythons-asyncio-worth-it--24lk
Is Python’s asyncio Worth It? - DEV Community
March 11, 2018 - I’ve been a Python (2) dev for around 5 years now; I’m not here to bash Python. That being said, one of the language’s few failings is its poor concurrency/parallelism story. There have been attempts to fight the GIL before, like Twisted, eventlet, and the standard library’s threading module, but the results have been (IMO) overengineered, overcomplicated, and just not...nice. Now there’s asyncio, which seems better, but still inferior to goroutines or Clojure’s core.async (which is basically goroutines), or the plethora of options presented by e.g.
🌐
YouTube
youtube.com › watch
Goroutines vs Asyncio: Choosing the Best for CPU-Bound Tasks Explained - YouTube
In this video, we dive into the world of concurrency by comparing Goroutines in Go and Asyncio in Python, specifically focusing on their performance in handl...
Published   December 19, 2024
Top answer
1 of 2
9

In Python terms, the event loop is built into Go. You would launch two goroutines with go async_say(...) and wait for them to complete, for example using a channel or a wait group.

A straightforward translation of your code to Go could look like this:

package main

import "fmt"
import "time"

func async_say(delay time.Duration, msg string, done chan bool) {
    time.Sleep(delay)
    fmt.Println(msg)
    done <- true
}

func main() {
    done1 := make(chan bool, 1)
    go async_say(4 * time.Second, "hello", done1)
    done2 := make(chan bool, 1)
    go async_say(6 * time.Second, "world", done2)
    <-done1
    <-done2
}

Note that, unlike Python (and JavaScript, etc.), Go functions do not come in different colors depending on whether they are asynchronous or not. They can all be run asynchronously, and the equivalent of asyncio is built into the standard library.

2 of 2
4

You don't need this in Go as in Go this would be an anti-pattern.

Instead, in Go, you have management of "pollable" descriptors — such as sockets — tightly integrated with the runtime and the goroutine scheduler. This allows you to write normal sequential code which will internally be handled via a platform-specific "eventful" interface (such as epoll on Linux, kqueue on FreeBSD and IOCP on Windows). As soon as a goroutine tries to perform any I/O on a socket and the socket is not ready, the goroutine gets suspended until that data is ready after which it will be resumed right at the place it has been suspended.

Hence in Go, you merely create a separate goroutine to serve each request which should be performed or served concurrently with the others and write plain sequential code to handle it.

For backrgound, start here and here.

The tutorials explaining how the Go scheduler works are, for instance, this and this.

🌐
Eli Bendersky
eli.thegreenplace.net › 2018 › go-hits-the-concurrency-nail-right-on-the-head
Go hits the concurrency nail right on the head - Eli Bendersky's website
But it's not just the switching time; goroutines also have small stacks that can grow at run-time (something thread stacks cannot do), which is also carefully tuned to be able to run millions of goroutines simultaneously. There's no magic here; consider this claim - if threads in C++ or JS or Python were extremely lightweight and fast, we wouldn't need async models.
🌐
GitHub
github.com › purplegrapeZz › goroutine-py
GitHub - purplegrapeZz/goroutine-py: 🚀 An Asyncio-based concurrency library for Python.
Easy concurrency just like goroutine without worry about thread and coroutine in Python. ... Withing goroutine.app.go you can run a coroutine or a func asynchronously. ... obj: Takes both callable coroutinefunction and func as object. *args: Arguments for your obj. callback: Attaches a callable that will be called when the future finishes. ... The primary entity of goroutine-py is goroutine.app.go. You can simply start using goroutine-py like this: ... import asyncio import time from goroutine.app import go # A normal func def task_1(n=2): time.sleep(n) print('Task_1_done') return 'Result_1' # A coroutinefunction async def task_2(n=1): await asyncio.sleep(n) print('Task_2_done') return 'Result_2' # Callback func def callback(result): ''' Parameter "result" is the return from task.
Author   purplegrapeZz
🌐
pythontutorials
pythontutorials.net › blog › start-async-function-without-importing-the-asyncio-package
Can You Start an Async Python Function Without Importing Asyncio? No Event Loop Needed: Goroutine-like Approach Explained — pythontutorials.net
So, can we run "async-like" code without asyncio or an event loop? The answer lies in simulating concurrency using Python’s threading and concurrent.futures modules. This approach mimics Go’s goroutines—lightweight, concurrent functions—by leveraging threads and futures.
🌐
Nexedi
nexedi.com › NXD-Presentation.Multicore.PyconFR.2018
Multi-core Python HTTP faster than Go
November 5, 2020 - A multi-core Python HTTP server (much) faster than Go (spoiler: Cython)