IMO, a coroutine implies supporting of explicit means for transferring control to another coroutine. That is, the programmer programs a coroutine in a way when they decide when a coroutine should suspend execution and pass its control to another coroutine (either by calling it or by returning/exiting (usually called yielding)).

Go's "goroutines" are another thing: they implicitly surrender control at certain indeterminate points1 which happen when the goroutine is about to sleep on some (external) resource like I/O completion, channel send etc. This approach combined with sharing state via channels enables the programmer to write the program logic as a set of sequential light-weight processes which removes the spaghetti code problem common to both coroutine- and event-based approaches.

Regarding the implementation, I think they're quite similar to the (unfortunately not too well-known) "State Threads" library, just quite lower-level (as Go doesn't rely on libc or things like this and talks directly to the OS kernel) — you could read the introductory paper for the ST library where the concept is quite well explained.


Update from 2023-08-25: Russ Cox has written a good essay on why a standard coroutine package for Go would be useful, and how it could look like.


1 In fact, these points are less determinate than those of coroutines but more determinate than with true OS threads under preemptive multitasking, where each thread might be suspended by the kernel at any given point in time and in the flow of the thread's control.
Update on 2021-05-28: actually, since Go 1.14, goroutines are scheduled (almost) preemptively. It should be noted though, that it's still not that hard-core preemption a typical kernel does to the threads it manages but it's quite closer than before; at least it's now impossible for a goroutine to become non-preemptible once it enters a busy loop.

Answer from kostix on Stack Overflow
Top answer
1 of 7
88

IMO, a coroutine implies supporting of explicit means for transferring control to another coroutine. That is, the programmer programs a coroutine in a way when they decide when a coroutine should suspend execution and pass its control to another coroutine (either by calling it or by returning/exiting (usually called yielding)).

Go's "goroutines" are another thing: they implicitly surrender control at certain indeterminate points1 which happen when the goroutine is about to sleep on some (external) resource like I/O completion, channel send etc. This approach combined with sharing state via channels enables the programmer to write the program logic as a set of sequential light-weight processes which removes the spaghetti code problem common to both coroutine- and event-based approaches.

Regarding the implementation, I think they're quite similar to the (unfortunately not too well-known) "State Threads" library, just quite lower-level (as Go doesn't rely on libc or things like this and talks directly to the OS kernel) — you could read the introductory paper for the ST library where the concept is quite well explained.


Update from 2023-08-25: Russ Cox has written a good essay on why a standard coroutine package for Go would be useful, and how it could look like.


1 In fact, these points are less determinate than those of coroutines but more determinate than with true OS threads under preemptive multitasking, where each thread might be suspended by the kernel at any given point in time and in the flow of the thread's control.
Update on 2021-05-28: actually, since Go 1.14, goroutines are scheduled (almost) preemptively. It should be noted though, that it's still not that hard-core preemption a typical kernel does to the threads it manages but it's quite closer than before; at least it's now impossible for a goroutine to become non-preemptible once it enters a busy loop.

2 of 7
68

Not quite. The Go FAQ section Why goroutines instead of threads? explains:

Goroutines are part of making concurrency easy to use. The idea, which has been around for a while, is to multiplex independently executing functions—coroutines—onto a set of threads. When a coroutine blocks, such as by calling a blocking system call, the run-time automatically moves other coroutines on the same operating system thread to a different, runnable thread so they won't be blocked. The programmer sees none of this, which is the point. The result, which we call goroutines, can be very cheap: they have little overhead beyond the memory for the stack, which is just a few kilobytes.

To make the stacks small, Go's run-time uses resizable, bounded stacks. A newly minted goroutine is given a few kilobytes, which is almost always enough. When it isn't, the run-time grows (and shrinks) the memory for storing the stack automatically, allowing many goroutines to live in a modest amount of memory. The CPU overhead averages about three cheap instructions per function call. It is practical to create hundreds of thousands of goroutines in the same address space. If goroutines were just threads, system resources would run out at a much smaller number.

🌐
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.
Discussions

Have there some like Goroutines in Python 3.13 or maybe 3.14
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? More on discuss.python.org
🌐 discuss.python.org
0
0
May 15, 2024
python 3.x - Goroutines vs asyncio tasks + thread pool for CPU-bound calls - Stack Overflow
Are goroutines roughly equivalent to python's asyncio tasks, with an additional feature that any CPU-bound task is routed to a ThreadPoolExecutor instead of being added to the event loop (of course... More on stackoverflow.com
🌐 stackoverflow.com
Advantage of coroutines above goroutines in 2023
This is a very interesting post from Russ cox, part of the go team at Google: https://research.swtch.com/coro This post is about why we need a coroutine package for Go, and what it would look like. But first, what are coroutines? More on reddit.com
🌐 r/golang
31
55
October 29, 2023
Generator-based coroutine vs async-based coroutine
i think there is a divide and confusion about what a coroutine is and the difference from an async coroutine. i'm not even sure what exactly you didn't understand. ex: Can we not implement sleep as an async-based coroutine? we already have asyncio.sleep. i'm not exactly sure what do you mean. More on reddit.com
🌐 r/learnpython
4
11
March 26, 2024
🌐
Reddit
reddit.com › r/python › how different is python concurrency vs. golang concurrency?
r/Python on Reddit: How different is python concurrency vs. Golang concurrency?
February 18, 2022 - Depends on what you know already. If you know what a thread is, read up on pythons threading and multiprocessing modules, and go's goroutines.
🌐
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 - Goroutines and Python Coroutines provide potent tools for concurrent programming, aiding responsiveness and scalability. By employing channels and asynchronous queues, tasks communicate effectively in both languages. ASGI and WASGI revolutionize web server interfaces, allowing developers to craft performant and responsive applications.
🌐
The Content Authority
thecontentauthority.com › home › grammar › word usage › goroutine vs coroutine: unraveling commonly confused terms
Goroutine vs Coroutine: Unraveling Commonly Confused Terms
June 27, 2023 - Goroutine refers to a lightweight thread of execution that allows for concurrent programming in Go. It’s a function that can be executed concurrently with other functions, without the need for explicit thread management.
🌐
O'Reilly
oreilly.com › library › view › go-building-web › 9781787123496 › ch19s03.html
Understanding goroutines versus coroutines - Go: Building Web Applications [Book]
August 31, 2016 - A coroutine is a cooperative task control mechanism, but in its most simplistic sense, a coroutine is not concurrent. While coroutines and goroutines are utilized in similar ways, Go's focus on concurrency provides a lot more than just state ...
Authors   Nathan KozyraMat Ryer
Published   2016
Pages   665
🌐
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?
Find elsewhere
🌐
Hacker News
news.ycombinator.com › item
Everything *can* be a coroutine (goroutine) in Go, very simple. Just add `go` be... | Hacker News
February 15, 2024 - It's literally as simple as it sounds: · https://gobyexample.com/goroutines
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.

🌐
Hacker News
news.ycombinator.com › item
Creating millions of coroutines or "goroutines" isn't really interesting by itse... | Hacker News
October 10, 2018 - 1. is Go scheduler better than Linux scheduler if you have a thousand concurrent goroutines or threads · 2. is really creating goroutines that much faster than creating a native thread
🌐
Madeddu
madeddu.xyz › posts › golang vs python: deep dive into the concurrency
GoLang vs Python: deep dive into the concurrency | madeddu.xyz
January 17, 2018 - When a coroutine blocks, such as by calling a blocking system call, the run-time automatically moves other coroutines on the same operating system thread to a different, runnable thread so they won’t be blocked. These coroutine are called goroutines and are very cheap: they have little overhead ...
🌐
Wikipedia
en.wikipedia.org › wiki › Coroutine
Coroutine - Wikipedia
1 week ago - A new goroutine can be started using the "go" keyword. Each goroutine has a variable-size stack which can be expanded as needed. Goroutines generally communicate using Go's built-in channels. However, goroutines are not coroutines (for instance, local data does not persist between successive calls).
🌐
DEV Community
dev.to › leapcell › concurrency-in-go-vs-rustc-goroutines-vs-coroutines-27f5
Concurrency in Go vs Rust/C++: Goroutines vs Coroutines - DEV Community
March 27, 2025 - Although the names and implementation methods of coroutines vary among different languages, essentially, coroutines are mainly divided into two categories: stackful coroutines and stackless coroutines. The former is represented by goroutines, and the latter is typified by async/await.
🌐
Yingw787
bytes.yingw787.com › posts › 2019 › 02 › 09 › concurrency_with_python_csp_and_coroutines
Concurrency with Python: CSP and Coroutines
Coroutines need to share lots of data across channels: Ravelin shared some information on golang channels that indicated sharing data between goroutines across channels was expensive in comparison to keeping data within a set goroutine. CSP channels are also inherently synchronous.
🌐
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
You can think of goroutines as threads, it's a fairly good mental model. They are truly cheap threads - because the Go runtime implements launching them and switching between them without deferring to the OS kernel.
🌐
Medium
leapcell.medium.com › concurrency-in-go-vs-rust-c-goroutines-vs-coroutines-b0fa4769b771
Concurrency in Go vs Rust/C++: Goroutines vs Coroutines | by Leapcell | Medium
March 27, 2025 - The core difference lies in whether a coroutine can be suspended in any nested function (such as a sub-function, anonymous function, etc.). Stackful coroutines have this ability, while stackless coroutines do not.
🌐
Google Groups
groups.google.com › g › golang-nuts › c › Onswx7FpdxY
Difference between CSP (channels) and coroutines (yield)
For example select statements on multiple goroutines, are equivalent to getting the value of the first coroutine, and hinting the evil scheduler to schedule the execution of the coroutines to make that the first coroutine computed. One thing you cannot implement with Python's coroutines, then, is something where you do c := make(chan int) and then kick off 5 goroutines generating data on c and 10 goroutines consuming data on c.
🌐
WikiDiff
wikidiff.com › goroutine › coroutine
Coroutine vs Goroutine - What's the difference? | WikiDiff
March 21, 2024 - As nouns the difference between coroutine and goroutine is that coroutine is (programming) a piece of code that performs a task, and that can be passed new input and return output more than once while goroutine is...