News for hackers. Stuff that matters.
Re:Python has had async for 10 years – why isn't it more pop... by atomicnumber3 on Tuesday September 02, 2025 @01:41PM (#45106455)
The author gets close to what I think the root problem is, but doesn't call it out.

The truth is that in python, async was too little, too late. By the time it was introduced, most people who actually needed to do lots of io concurrently had their own workarounds (forking, etc) and people who didn't actually need it had found out how to get by without it (multiprocessing etc).

Meanwhile, go showed us what good green threads can look like. Then java did it too. Meanwhile, js had better async support the whole time. But all it did was show us that async code just plain sucks compared to green thread code that can just block, instead of having to do the async dances.

So, why engage with it when you already had good solutions?

Re:Python has had async for 10 years – why isn't it more pop... by throw-qqqqq on Tuesday September 02, 2025 @01:51PM (#45106616)
> But all it did was show us that async code just plain sucks compared to green thread code that can just block, instead of having to do the async dances.

I take so much flak for this opinion at work, but I agree with you 100%.

Code that looks synchronous, but is really async, has funny failure modes and idiosyncracies, and I generally see more bugs in the async parts of our code at work.

Maybe I’m just old, but I don’t think it’s worth it. Syntactic sugar over continuations/closures basically..

Re:Python has had async for 10 years – why isn't it more pop... by lacker on Tuesday September 02, 2025 @02:04PM (#45106801)
I'm confused, I feel like the two of you are expressing opposite opinions.

The comment you are responding to prefers green threads to be managed like goroutines, where the code looks synchronous, but really it's cooperative multitasking managed by the runtime, to explicit async/await.

But then you criticize "code that looks synchronous but is really async". So you prefer the explicit "async" keywords? What exactly is your preferred model here?

Re:Python has had async for 10 years – why isn't it more pop... by throw-qqqqq on Tuesday September 02, 2025 @02:34PM (#45107191)
First, I don’t mean to criticize anything or anyone. People value such things subjectively, but for me the async/sync split does no good.

Goroutines feel like old-school, threaded code to me. I spawn a goroutine and interact with other “threads” through well defined IPC. I can’t tell if I’m spawning a green thread or a “real” system thread.

C#’s async/await is different IMO and I prefer the other model. I think the async-concept gets overused (at my workplace at least).

If you know Haskell, I would compare it to overuse of laziness, when strictness would likely use fewer resources and be much easier to reason about. I see many of the same problems/bugs with async/await..

Re:Python has had async for 10 years – why isn't it more pop... by eddd-ddde on Tuesday September 02, 2025 @06:45PM (#45110079)
Wouldn't the old school style be more like rust async? Simple structs that you poll whenever you need to explicitly. No magic code that looks synchronous but isn't.
Re:Python has had async for 10 years – why isn't it more pop... by tptacek on Tuesday September 02, 2025 @08:48PM (#45111029)
No, Rust async is new-school colored-functions concurrency.
Re:Python has had async for 10 years – why isn't it more pop... by pkolaczk on Wednesday September 03, 2025 @12:54AM (#45112367)
The parent comment is right. Rust async is simple state automata structs you can poll explicitly with no magic. Async/await is just some syntactic sugar on top of that, but you don’t have to use it.

An obvious advantage of doing it that way is you don’t need any runtime/OS-level support. Eg your runtime doesn’t need to even have a concept of threads. It works on bare metal embedded.

Another advantage is that it’s fully cooperative model. No magic preemption. You control the points where the switch can happen, there is no magic stuff suddenly running in background and messing up the state.

Re:Python has had async for 10 years – why isn't it more pop... by jpc0 on Wednesday September 03, 2025 @04:42AM (#45113540)
Have you actually tried to implement async in rust from the ground up.

It is nothing like what you just described

Re:Python has had async for 10 years – why isn't it more pop... by tptacek on Wednesday September 03, 2025 @08:54AM (#45115125)
I didn't say it was good or bad. I said it's new-school colored functions.
Re:Python has had async for 10 years – why isn't it more pop... by thomasahle on Tuesday September 02, 2025 @07:20PM (#45110379)
Comparing to Haskell, I think of "async" as the IO monad. It's nice to have all code that does IO flagged explicitly as such.
Re:Python has had async for 10 years – why isn't it more pop... by raxxorraxor on Wednesday September 03, 2025 @02:55AM (#45112979)
> I think the async-concept gets overused (at my workplace at least).

Problem is it that it self reinforces and before you look every little function is suddenly async.

The irony is that it is used where you want to write in a synchronous style...

Re:Python has had async for 10 years – why isn't it more pop... by carlmr on Wednesday September 03, 2025 @05:36AM (#45113857)
Yep, this is my biggest gripe with explicit async, all of a sudden a library that needn't be async forces me to use async (and in Rust forces me to use their async implementation), just because the author felt like async is a nice thing to try out.
Re:Python has had async for 10 years – why isn't it more pop... by sfn42 on Wednesday September 03, 2025 @04:56AM (#45113621)
I always find it strange how people complain about features when the real problem is that they simply don't like how people use the feature.

Async in C# is awesome, and there's nothing stopping you from writing sync code where appropriate or using threads if you want proper multi threading. Async is primarily used to avoid blocking for non-cpu-bound work, like waiting for API/db/filesystem etc. If you use it everywhere then it's used everywhere, if you don't then it isn't. For a lot of apps it makes sense to use it a lot, like in web apis that do lots of db calls and such. This incurs some overhead but it has the benefit of avoiding blocked threads so that no threads sit idle waiting for I/O.

You can imagine in a web API receiving a large number of requests per second there's a lot of this waiting going on and if threads were idle waiting for responses you wouldn't be able to handle nearly as much throughout.

Re:Python has had async for 10 years – why isn't it more pop... by throwaway81523 on Tuesday September 02, 2025 @05:36PM (#45109392)
No, goroutines are preemptive. They avoid async hazards though of course introduce some different ones.
Re:Python has had async for 10 years – why isn't it more pop... by Yoric on Tuesday September 02, 2025 @05:59PM (#45109667)
To be fair, it depends on the version of Go.

Used to be well-hidden cooperative, these days it's preemptive.

Re:Python has had async for 10 years – why isn't it more pop... by throwaway81523 on Tuesday September 02, 2025 @06:34PM (#45110006)
It changed for a reason.
Re:Python has had async for 10 years – why isn't it more pop... by kibwen on Tuesday September 02, 2025 @02:03PM (#45106787)
> Code that looks synchronous, but is really async, has funny failure modes and idiosyncracies

But this appears to be describing languages with green threads, rather than languages that make async explicit.

Re:Python has had async for 10 years – why isn't it more pop... by pclmulqdq on Tuesday September 02, 2025 @02:11PM (#45106901)
Without the "async" keyword, you can still write async code. It looks totally different because you have to control the state machine of task scheduling. Green threads are a step further than the async keyword because they have none of the function coloring stuff.

You may think of use of an async keyword as explicit async code but that is very much not the case.

If you want to see async code without the keyword, most of the code of Linux is asynchronous.

Re:Python has had async for 10 years – why isn't it more pop... by throw-qqqqq on Tuesday September 02, 2025 @02:57PM (#45107497)
This is exactly what I mean.

Thank you for explaining much more clearly than I could.

> none of the function coloring stuff

And it’s this part that I don’t like (and see colleagues struggling to implement correctly at work).

Re:Python has had async for 10 years – why isn't it more pop... by Dylan16807 on Tuesday September 02, 2025 @02:55PM (#45107465)
Having to put "await" everywhere is very explicit. I'd even say it's equally explicit to a bunch of awkward closures. Why do you say it's less?
Re:Python has had async for 10 years – why isn't it more pop... by pclmulqdq on Tuesday September 02, 2025 @03:17PM (#45107736)
It's explicit that the code is async, but how the asynchrony happens is completely implicit with async/await, and is managed by a runtime of some kind.

Kernel-style async code, where everything is explicit:

* You write a poller that opens up queues and reads structs representing work

* Your functions are not tagged as "async" but they do not block

* When those functions finish, you explicitly put that struct in another queue based on the result

Async-await code, where the runtime is implicit:

* All async functions are marked and you await them if they might block

* A runtime of some sort handles queueing and runnability

Green threads, where all asynchrony is implicit:

* Functions are functions and can block

* A runtime wraps everything that can block to switch to other local work before yielding back to the kernel

Re:Python has had async for 10 years – why isn't it more pop... by lstodd on Tuesday September 02, 2025 @05:25PM (#45109259)
> Green threads, where all asynchrony is implicit:

which are no different from app POV from kernel threads, or any threads for that matter.

the whole async stuff came up because context switch per event is way more expensive than just shoveling down a page of file descriptor state.

thus poll, kqueue, epoll, io_uring, whatever.

think of it as batch processing

Re:Python has had async for 10 years – why isn't it more pop... by throw-qqqqq on Tuesday September 02, 2025 @03:04PM (#45107594)
> Why do you say it's less

Let me try to clarify my point of view:

I don’t mean that async/await is more or less explicit than goroutines. I mean regular threaded code is more explicit than async/await code, and I prefer that.

I see colleagues struggle to correctly analyze resource usage for instance. Someone tries to parallelize some code (perhaps naiively) by converting it to async/await and then run out of memory.

Again, I don’t mean to judge anyone. I just observe that the async/await-flavor has more bugs in the code bases I work on.

Re:Python has had async for 10 years – why isn't it more pop... by curt15 on Tuesday September 02, 2025 @05:00PM (#45108983)
>I don’t mean that async/await is more or less explicit than goroutines. I mean regular threaded code is more explicit than async/await code, and I prefer that.

More explicit in what sense? I've written both regular threaded Python and async/await Python. Only the latter shows me precisely where the context switches occur.

Re:Python has had async for 10 years – why isn't it more pop... by throwawayffffas on Tuesday September 02, 2025 @05:37PM (#45109407)
Because it hides away the underlying machinery.

Everything is in a run loop that does not exist in my codebase.

The context switching points are obvious but the execution environment is opaque.

At least that's how it looks to me.

Re:Python has had async for 10 years – why isn't it more pop... by toast0 on Tuesday September 02, 2025 @06:38PM (#45110028)
The problem isn't that it hides away the machinery. The problem is that it hides some things, but not everything. Certainly a lot of stuff hides behind await/async. But as a naive developer who is used to real threads and green threads, I expected there would be some wait to await on a real thread and all the async stuff would just happen... but instead, if you await, actually you've got to be async too. If you had to write your async code where you gave an eventloop a FD and a callback to run when it was ready, that would be more explicit, IMHO... but it would be so wordy that it would only get used under extreme duress... I've worked on those code bases and they can do amazing things, but if there's any complexity it quickly becomes not worth it.

Green threads are better (IMHO), because they actually do hide all the machinery. As a developer in a language with mature green threads (Erlang), I don't have to know about the machinery[1], I just write code that blocks from my perspective and BEAM makes magic happen. As I understand it, that's the model for Java's Project Loom aka Java Green Threads 2: 2 Green 2 Threads. The first release had some issues with the machinery, but I think I read the second release was much better, and I haven't seen much since... I'm not a Cafe Babe, so I don't follow Java that closely.

[1] It's always nice to know about the machinery, but I don't have to know about it, and I was able to get started pretty quick and figure out the machinery later.

Re:Python has had async for 10 years – why isn't it more pop... by worthless-trash on Wednesday September 03, 2025 @02:44AM (#45112899)
I don't know who you are, but thanks.. My beam code goes brrrr.. so fast, much async, so reliable, no worries.
Re:Python has had async for 10 years – why isn't it more pop... by ForHackernews on Tuesday September 02, 2025 @06:04PM (#45109726)
I don't understand this criticism. The JVM is opaque, App Engine is opaque, Docker is opaque. All execution environments are opaque unless you've attached a debugger and are manually poking at the thing while it runs.
Re:Python has had async for 10 years – why isn't it more pop... by pclmulqdq on Tuesday September 02, 2025 @10:52PM (#45111809)
Some are more opaque than others.
Re:Python has had async for 10 years – why isn't it more pop... by lstodd on Thursday September 04, 2025 @02:00PM (#45130204)
If those persist in opaqueness, say "confess, or I fetch Ghidra".

If even this does not help, rm -rf is your friend.

Re:Python has had async for 10 years – why isn't it more pop... by vova_hn on Tuesday September 02, 2025 @10:32PM (#45111699)
> Green threads are a step further than the async keyword because they have none of the function coloring stuff.

I would say that green threads still have "function coloring stuff", we just decided that every function will be async-colored.

Now, what happens if you try to cross an FFI-border and try to call a function that knows nothing about your green-thread runtime is an entirely different story...

Re:Python has had async for 10 years – why isn't it more pop... by larusso on Tuesday September 02, 2025 @02:13PM (#45106917)
async is like a virus. I think the implementation in js and .NET is somewhat ok’ish because your code is inside an async context most of the time. I really hate the red / blue method issues where library functions get harder to compose. Oh I have a normal method because there was no need for async. Now I change the implementation and need to call an async method. There are ways around this but more often than not will you change most methods to be async.

To be fair that also happens with other solutions.

Re:Python has had async for 10 years – why isn't it more pop... by DanielHB on Tuesday September 02, 2025 @04:03PM (#45108296)
It is not nearly as much of a problem in JS because JS only has an event loop, there is no way to mix in threads with async code because there are no threads. Makes everything a lot simpler and a lot of the data structures a lot faster (because no locks required). But actual parallelization (instead of just concurrency) is impossible.

A lot of the async problems in other languages is because they haven't bought up into the concept fully with some 3rd party code using it and some don't. JS went all-in with async.

: Yes I know about service workers, but they are not threads in the sense that there is no shared memory. It is good for some types of parallelization problems, but not others because of all the memory copying required.

2: Yes I know about SharedArrayBuffer and there is a bunch of proposals to add support for locks and all that fun stuff to them, which also brings all the complexity back.

Re:Python has had async for 10 years – why isn't it more pop... by _moof on Tuesday September 02, 2025 @11:15PM (#45111922)
In my less charitable moments, I've wondered if the real reason Python has async/await is because people coming to it from JavaScript couldn't be arsed to learn a more appropriate paradigm.
Re:Python has had async for 10 years – why isn't it more pop... by markandrewj on Tuesday September 02, 2025 @05:30PM (#45109308)
I can tell you guys work with languages like Go, so this isn't true for yourselves, but I usually find it is developers that only ever work with synchronous code who find async complicated. Which isn't surprising, if you don't understand something it can seem complicated. My views is almost that people should learn how to write async code by default now. Regardless of the language. Writing modern applications basically requires it, although not all the time obviously.
Re:Python has had async for 10 years – why isn't it more pop... by Yoric on Tuesday September 02, 2025 @06:01PM (#45109694)
Hey, I'm one of the (many, many) people who made async in JavaScript happen and I find async complicated.
Re:Python has had async for 10 years – why isn't it more pop... by markandrewj on Tuesday September 02, 2025 @11:05PM (#45111865)
Hey Yoric, I do not want to underplay what it is like to work with async, but I think there has been a lot of improvements to make it easier, especially in JavaScript/ECMAScript. It is nice not to have to work directly with promises in the same way that was required previously. The language has matured a lot since I started using in Netscape Navigator (I see you formerly worked at Mozilla). I think coding can be complicated in general, although it shouldn't have to be. I think having a mental model for async from the start can be helpful, and understanding the difference between blocking and non blocking code. A lot of people learned writing synchronous code first, so I think it can be hard to develop the mental model and intuit it.
Re:Python has had async for 10 years – why isn't it more pop... by ErikBjare on Wednesday September 03, 2025 @02:34AM (#45112847)
I have no problem with async in JS or Rust, but async in Python is a very different beast, and like many people in this thread I do my best to avoid the fully loaded footgun altogether. Writing maintainable Python basically requires avoiding it, so I strongly disagree with "regardless of language".
Re:Python has had async for 10 years – why isn't it more pop... by markandrewj on Wednesday September 03, 2025 @09:06AM (#45115260)
Maybe, but I wouldn't go back to Python 2 without async. It has also improved over time in Python. I have also had success using async in Python. I do understand what the article talks about however. Understanding the difference between blocking and non-blocking code is also a concept relevant to Python. In Node it's one of the concepts you are first introduced to, because Node is single threaded by default. I also understand in Go and other languages there are different options.

https://nodejs.org/en/learn/asynchronous-work/overview-of-bl...

I will agree with what some is said a above, BEAM is pretty great. I have been using it recently through Elixir.

Re:Python has had async for 10 years – why isn't it more pop... by Uptrenda on Tuesday September 02, 2025 @05:54PM (#45109618)
I'm a person who wrote an entire networking library in Python and I agree with you. The most obvious issue with Python's single-threaded async code is any slow part of the program delays the entire thing. And yeah -- that's actually insanely frigging difficult to avoid. You write standard networking code and then find out that parts you expected to be async in Python actually ended up being sync / blocking.

DESPITE THAT: even if you're doing everything "right" (TM) -- using a single thread and doing all your networking I/O sequentially is simply slow as hell. A very very good example of this is bottle.py. Lets say you host a static web server with bottle.py. Every single web request for files leads to sequential loading, which makes page load times absolutely laughable. This isn't the case for every python web frame work, but it seems to be a common theme to me. (Cause: single thread, event loop.)

With asyncio, the most consistent behavior I've had with it seems to be to avoid having multiple processes and then running event loops inside them. Even though this approach seems like its necessary (or at least threading) to avoid the massive down sides of the event loop. But yeah, you have to keep everything simple. In my own library I use a single event loop and don't do anything fancy. I've learned the hard way how asyncio punishes trying to improve it. It's a damn cool piece of software, just has some huge limitations for performance.

Re:Python has had async for 10 years – why isn't it more pop... by fulafel on Wednesday September 03, 2025 @12:58AM (#45112383)
bottle.py is a WSGI backed framework, right? So it's agnostic about whether you are running with threads, fork, blocking single thread IO, gevent, or what.
Re:Python has had async for 10 years – why isn't it more pop... by Uptrenda on Wednesday September 03, 2025 @01:14AM (#45112434)
Umm, acktually... (the default server is non-threaded and sequential. It was an example.)
Re:Python has had async for 10 years – why isn't it more pop... by pnathan on Tuesday September 02, 2025 @02:31PM (#45107148)
Async taints code, and async/await fall prey to classic cooperative multitasking issues. "What do you mean that this blocked that?"

The memory and execution model for higher level work needs to not have async. Go is the canonical example of it done well from the user standpoint IMO.

Re:Python has had async for 10 years – why isn't it more pop... by hinkley on Tuesday September 02, 2025 @05:01PM (#45108994)
The function color thing is a real concern. Am I wrong or did a python user originally coin that idea?
Re:Python has had async for 10 years – why isn't it more pop... by throwawayffffas on Tuesday September 02, 2025 @06:05PM (#45109738)
No it was a js dev complaining about callbacks in node. Mainly because a lot of standard library code back then only came in callback flavour. i.e. no sync file writes, etc.
Re:Python has had async for 10 years – why isn't it more pop... by munificent on Tuesday September 02, 2025 @07:18PM (#45110369)
I wrote it. :)

Actually, I was and am primarily a Dart developer, not a JS developer. But function color is a problem in any language that uses that style of asynchrony: JS, Dart, etc.

Re:Python has had async for 10 years – why isn't it more pop... by LtWorf on Tuesday September 02, 2025 @06:47PM (#45110108)
Which is really funny because the linux kernel doesn't do async for file writes :D
Re:Python has had async for 10 years – why isn't it more pop... by yxhuvud on Wednesday September 03, 2025 @01:59AM (#45112644)
Uh, io_uring does that just fine.
Re:Python has had async for 10 years – why isn't it more pop... by LtWorf on Wednesday September 03, 2025 @01:59AM (#45112649)
That's yet another thing though.
Re:Python has had async for 10 years – why isn't it more pop... by yxhuvud on Friday September 05, 2025 @02:08AM (#45135437)
It is part of the kernel and it does async file writes, so I don't really understand your objection.
Re:Python has had async for 10 years – why isn't it more pop... by meowface on Tuesday September 02, 2025 @07:21PM (#45110383)
gevent has been in Python for ages and still works great. It basically adds goroutine-like green thread support to the language. I still generally start new projects with gevent instead of asyncio, and I think I always will.
Re:Python has had async for 10 years – why isn't it more pop... by pdonis on Tuesday September 02, 2025 @08:00PM (#45110681)
I've used gevent and I agree it works well. It has prevented me from even trying to experiment with the async/await syntax in Python for anything significant.

However, gevent has to do its magic by monkeypatching. Wanting to avoid that, IIRC, was a significant reason why the async/await syntax and the underlying runtime implementation was developed for Python.

Another significant reason, of course, was wanting to make async functions look more like sync functions, instead of having to be written very differently from the ground up. Unfortunately, requiring the "async" keyword for any async function seriously detracted from that goal.

To me, async functions should have worked like generator functions: when generators were introduced into Python, you didn't have to write "gen def" or something like it instead of just "def" to declare one. If the function had the "yield" keyword in it, it was a generator. Similarly, if a function has the "await" keyword in it, it should just automatically be an async function, without having to use "async def" to declare it.

Re:Python has had async for 10 years – why isn't it more pop... by krmboya on Tuesday September 02, 2025 @11:35PM (#45112022)
Would this result in surprises like if a function is turned to async by adding an await keyword, all of a sudden all functions that have it in their call stack become async
Re:Python has had async for 10 years – why isn't it more pop... by pdonis on Wednesday September 03, 2025 @01:09PM (#45118182)
It would work the same as it works now for generators. A function that calls a generator function isn't a generator just because of that; it only is if it also has the yield keyword in it (or yield from, which is a way of chaining generators).

Similarly, a function that calls an async function wouldn't itself be async unless it also had the await keyword. But of course the usual way of calling an async function would be to await it. And calling it without awaiting it wouldn't return a value, just as with a generator; calling a generator function without yielding from it returns a generator object, and calling an async function without awaiting it would return a future object. You could then await the future later, or pass it to some other function that awaited it.

Re:Python has had async for 10 years – why isn't it more pop... by b33j0r on Tuesday September 02, 2025 @02:39PM (#45107247)
For me, once I wanted to scale asyncio within one process (scaling horizontally on top of that), only two things made sense: rust with tokio or node.js.

Doing async in python has the same fundamental design. You have an executer, a scheduler, and event-driven wakers on futures or promises. But you’re doing it in a fundamentally hand-cuffed environment.

You don’t get benefits like static compilation, real work-stealing, a large library ecosystem, or crazy performance boosts. Except in certain places in the stack.

Using fastapi with async is a game-changer. Writing a cli to download a bunch of stuff in parallel is great.

But if you want to use async to parse faster or make a parallel-friendly GUI, you are more than likely wasting your time using python. The benefits will be bottlenecked by other language design features. Still the GIL mostly.

I guess there is no reason you can’t make tokio in python with multiprocessing or subinterpreters, but to my knowledge that hasn’t been done.

Learning tokio was way more fun, too.

Re:Python has had async for 10 years – why isn't it more pop... by ciupicri on Tuesday September 02, 2025 @02:58PM (#45107510)
GIL is not part of the language design, it's just a detail of the most common implementation - CPython.
Re:Python has had async for 10 years – why isn't it more pop... by b33j0r on Tuesday September 02, 2025 @03:02PM (#45107559)
Fair and accurate. But that’s pretty much what people use, right?

I am happy to hear stories of using pypy or something to radically improve an architecture. I don’t have any from personal experience.

I guess twisted and stackless, a long time ago.

Re:Python has had async for 10 years – why isn't it more pop... by miohtama on Wednesday September 03, 2025 @01:36AM (#45112527)
The GIL is optional in new Python versions. Downsides are legacy library compatibility and degraded single thread performance.
Re:Python has had async for 10 years – why isn't it more pop... by b33j0r on Wednesday September 03, 2025 @07:54PM (#45121734)
I mentioned subinterpreters. That’s the thing that “makes the GIL optional,” you still have to use subinterpreters.

Is this no longer true?

Re:Python has had async for 10 years – why isn't it more pop... by miohtama on Friday September 05, 2025 @12:55AM (#45135097)
It is no longer true. You can have free threading.
Re:Python has had async for 10 years – why isn't it more pop... by smw on Tuesday September 02, 2025 @02:47PM (#45107352)
Or just golang?
Re:Python has had async for 10 years – why isn't it more pop... by iknowstuff on Tuesday September 02, 2025 @02:56PM (#45107484)
Segfaults
Re:Python has had async for 10 years – why isn't it more pop... by hinkley on Tuesday September 02, 2025 @05:06PM (#45109059)
I don’t know where Java is now but their early promise and task queue implementations left me feeling flat. And people who should know better made some dumb mistakes around thread to CPU decisions that just screamed “toy solution”. They didn’t compose.
Re:Python has had async for 10 years – why isn't it more pop... by gen220 on Tuesday September 02, 2025 @02:01PM (#45106758)
As somebody who's written and maintained a good bit of Python in prod and recently a good amount of server-side typescript... this would be my answer.

I'd add one other aspect that we sort of take for granted these days, but affordable multi-threaded CPUs have really taken off in the last 10 years.

Not only does the stack based on green-threads "just work" without coloring your codebase with async/no-async, it allows you to scale a single compute instance gracefully to 1 instance with N vCPUs vs N pods of 2-vCPU instances.

Re:Python has had async for 10 years – why isn't it more pop... by gshulegaard on Tuesday September 02, 2025 @03:26PM (#45107865)
I also think asyncio missed the mark when it comes to it's API design. There are a lot of quirks and rough edges to it that, as someone who was using `gevent` heavily before, strike me as curious and even anti-productive.
Re:Python has had async for 10 years – why isn't it more pop... by jayd16 on Tuesday September 02, 2025 @02:23PM (#45107048)
> But all it did was show us that async code just plain sucks compared to green thread code that can just block, instead of having to do the async dances.

I'll be sold on this when a green thread native UI paradigm becomes popular but it seems like all the languages with good native UI stories have async support.

Re:Python has had async for 10 years – why isn't it more pop... by neuroelectron on Tuesday September 02, 2025 @01:47PM (#45106558)
Even in Java, async is rarely the right solution. I'm sure in situations where it's needed, Python's async would be used. For instance, it would be good for reducing resource usage in any kind of small service that dynamically scales. The workarounds are much more expensive but that doesn't matter unless you're already resource constrained.

Even then, nginx might be a netter solution.

Re:Python has had async for 10 years – why isn't it more pop... by parhamn on Tuesday September 02, 2025 @01:55PM (#45106663)
pair this with needing async in depth and that's exactly it. The whole network stack needs to be async-first and all the popular networking libraries need to have been built on that. Many of those libraries are already C-extension based and don't jibe well with the newer python parts in any way.
Re:Python has had async for 10 years – why isn't it more pop... by hinkley on Tuesday September 02, 2025 @05:18PM (#45109180)
Java is trying to do this but I haven’t read how that’s going.
Re:Python has had async for 10 years – why isn't it more pop... by ddorian43 on Tuesday September 02, 2025 @01:54PM (#45106659)
Because it sucks compared to gevent (green threads). But for some reason, people always disregard this option. They don't even read it. Like any comment with gevent is shadowbanned and it doesn't register in their mind.
Re:Python has had async for 10 years – why isn't it more pop... by nromiun on Tuesday September 02, 2025 @02:32PM (#45107159)
Gevent is too underrated. Even if people don't like the monkey patching you can simply use the gevent namespace API as well. No idea why people prefer the absolute mess that is Python async ecosystem.
Re:Python has had async for 10 years – why isn't it more pop... by jononor on Tuesday September 02, 2025 @02:40PM (#45107261)
Happily using gevent for our backend (IoT+ML) since 2019. Was very glad when I saw it is still being well supported by recent SQLAlchemy and pscycopg releases.
Re:Python has had async for 10 years – why isn't it more pop... by int_19h on Tuesday September 02, 2025 @05:32PM (#45109339)
The fundamental problem with any kind of green threads is that they require runtime support which doesn't play well with any active stack frames that aren't aware that they are on a green thread (which can be switched).
Re:Python has had async for 10 years – why isn't it more pop... by meowface on Tuesday September 02, 2025 @07:22PM (#45110397)
I've used gevent for years and will probably never stop. I greatly prefer it (or Go) over asyncio.

People act like it's dead but it still works perfectly well and, at least for me, makes async networking so much simpler.

Re:Python has had async for 10 years – why isn't it more pop... by pulse7 on Tuesday September 02, 2025 @03:14PM (#45107701)
"Then java did it too." Java had green threads in 1.0. They were removed. Then Java added virtual threads.
Re:Python has had async for 10 years – why isn't it more pop... by JackSlateur on Tuesday September 02, 2025 @01:56PM (#45106684)
green thread have pitfalls too, like this: https://news.ycombinator.com/item?id=39008026
Re:Python has had async for 10 years – why isn't it more pop... by kasperni on Tuesday September 02, 2025 @02:27PM (#45107095)
This was a known issue and was fixed in Java 24 [1].

[1] https://openjdk.org/jeps/491

Re:Python has had async for 10 years – why isn't it more pop... by ronsor on Tuesday September 02, 2025 @02:03PM (#45106788)
This doesn't look like a problem with green threads so much as it is a problem with Java's implementation of them. Of course, Java is known for having problems with its implementations of many different things, such as sandboxing; this isn't special.
Re:Python has had async for 10 years – why isn't it more pop... by hueho on Tuesday September 02, 2025 @04:23PM (#45108514)
FWIW this was largely fixed in 24 (I think there are still some edge cases relating to FFI functionality), and the 25 LTS should be coming this month.
Re:Python has had async for 10 years – why isn't it more pop... by pbalau on Tuesday September 02, 2025 @02:51PM (#45107394)
You make a very good case for why python's async isn't more prevalent, but I think this is not painting the full image.

Taking a general case, let's say a forum, in order to render a thread one needs to search for all posts from that thread, then get all the extra data needed for rendering and finally send the rendered output to the client.

In the "regular" way of doing this, one will compose a query, that will filter things out, join all the required data bla bla, send it to the database, wait for the answer from the database and all the data to be transferred over, loop over the results and do some rendering and send the thing over to the client.

It doesn't matter how async your app code is, in this way of doing things, the bottle neck is the database, as there is a fixed limit on how many things a db server can do at once and if doing one of these things takes a long time, you still end up waiting too much.

In order for async to work, one needs to split the work load into very small chunks that can be done in parallel and very fast, therefore, sending a big query and waiting for all the result data is out of the window.

An async approach would split the db query into a search query, that returns a list of object ids, say posts, then create N number of async tasks that given a post id will return a rendered result. These tasks will do their own query to retrieve the post data, then assemble another list of async tasks to get all the other data required and render each chunk and so on. Throw in a bunch of db replicas and you get the benefits of async.

This approach is not generally used, because, let's face it, we like making the systems we use do complicated things, eg complicated sql requests.

Re:Python has had async for 10 years – why isn't it more pop... by LtWorf on Tuesday September 02, 2025 @10:36PM (#45111723)
Why do you think that all of that extra compute work would be better?
Re:Python has had async for 10 years – why isn't it more pop... by zelphirkalt on Wednesday September 03, 2025 @05:37AM (#45113872)
When I read your comment I was thinking: "But then you would need to structure your db in such a way that ... ahh yes, they are getting to that ... but then what about actually rendering the results? Ah they are describing that here ..." so well done I think.

However, async tasks on a single core means potentially a lot of switching between those tasks. So async alone does not save the day here. It will have to be combined with true parallelism, to result in the speedup we want. Otherwise a single task rendering all the parts in sequence would be faster.

Also not, that it depends on where your db is. the process you describe implies at least 2 rounds of db communication. First one for the initial get forum thread query, then second one for all the async get forum replies requests. So if communication with the db takes a long time, you might as well lose what you gained, because you did 2 rounds of that communication.

So I guess it's not a trivial matter.

Re:Python has had async for 10 years – why isn't it more pop... by pbalau on Wednesday September 03, 2025 @02:02PM (#45118732)
I think there is a bit of misunderstanding about what my post was about: it is not enough to make your app code async if you don't have all the infra to support that, hence why async in python didn't take the world by storm.
Re:Python has had async for 10 years – why isn't it more pop... by TZubiri on Tuesday September 02, 2025 @04:22PM (#45108486)
>most people who actually needed to do lots of io concurrently had their own workarounds (forking, etc) and people who didn't actually need it had found out how to get by without it (multiprocessing etc).

The problem is not python, it's a skill issue.

First of all forking is not a workaround, it's the way multiprocessing works at the low level in Unix systems.

Second of all, forking is multiprocessing, not multithreading.

Third of all, there's the standard threading library which just works well. There's no issue here, you don't need async.

Re:Python has had async for 10 years – why isn't it more pop... by zelphirkalt on Wednesday September 03, 2025 @05:23AM (#45113798)
Recently, I am working on a project that uses Threading (in Python) and so far have had zero issues with that. Neither did I have any issues before, when using multiprocessing.

What I did have issues with though, was async. For example pytest's async thingy is buggy for years with no fix in sight, so in one project I had to switch to manually making an event loop in that those tests.

But isn't the whole purpose of async, that it enabled concurrency, not parallelism, without the weight of a thread? I agree that in most cases it is not necessary to go there, but I can imagine systems with not so many resources, that benefit from such an approach when they do lots of io.

Re:Python has had async for 10 years – why isn't it more pop... by fabioyy on Thursday September 04, 2025 @11:45AM (#45128571)
fork is extremely heavy, threads are way lighter, but still opening thousands of threads can become a problem. opening a thread just to wait for a socket operation don't make sense. and the low level requirements to use ( select/iopool syscalls ) is hard. coroutines of async/await solve this problem.
Re:Python has had async for 10 years – why isn't it more pop... by hinkley on Tuesday September 02, 2025 @04:59PM (#45108978)
Async is pretty good “green threads” on its own. Coroutines can be better, but they’re really solving an overlapping set of problems. Some the same, some different.

In JavaScript async doesn’t have a good way to nice your tasks, which is an important feature of green threads. Sindre Sorhus has a bunch of libraries that get close, but there’s still a hole.

What coroutines can do is optimize the instruction cache. But I’m not sure goroutines entirely accomplish that. There’s nothing preventing them from doing so but implementation details.

Re:Python has had async for 10 years – why isn't it more pop... by leecarraher on Tuesday September 02, 2025 @05:13PM (#45109142)
i agree, also add to that, that many python modules are foss projects that are maintained on a limited basis or budget. Refactoring code that may have some unsafe async routines would be costly for an org, and dreadful for recreation. So you can either have a rich library of modules, or go async and risk something you need not working then having to find a workaround. Personally, if parallelism is important enough, i use ctypes and openmp. If i need something more portable, i have a few multiprocessing wrappers that implement prange and a few other widgets for shared memory.
Re:Python has had async for 10 years – why isn't it more pop... by jongjong on Tuesday September 02, 2025 @05:53PM (#45109610)
Yes and JS had a smooth on-ramp to async/await thanks to Promises.

Promises/thenables gave people the time to get used to the idea of deferred evaluation via a familiar callback approach... Then when async/await came along, people didn't see it as a radically new feature but more as syntactic sugar to do what they were already doing in a more succinct way without callbacks.

People in the Node.js community were very aware of async concepts since the beginning and put a lot of effort in not blocking the event loop. So Promises and then async/await were seen as solutions to existing pain points which everyone was already familiar with. A lot of people refactored their existing code to async/await.

Re:Python has had async for 10 years – why isn't it more pop... by laurencerowe on Tuesday September 02, 2025 @06:51PM (#45110140)
JavaScript’s Promises were of course heavily influenced by Twisted’s Deferreds in Python, from the days before async/await.
Re:Python has had async for 10 years – why isn't it more pop... by 6r17 on Tuesday September 02, 2025 @06:29PM (#45109958)
I feel like async is just an easier way to reason about something but it leaves out a lot of cheating open ; tough sometimes it's just more comfortable to write - but that cheating comes with a lot of hidden responsibilities that are just not presented in python (things like ownership) - even tough it present tools to properly solve these issues - anyone who would really want to dive into technical wouldn't choose python anyway
Re:Python has had async for 10 years – why isn't it more pop... by LtWorf on Tuesday September 02, 2025 @06:39PM (#45110033)
forking and async are totally different things.
Re:Python has had async for 10 years – why isn't it more pop... by pkulak on Tuesday September 02, 2025 @06:41PM (#45110052)
Green threads can be nicer to program in, but it’s not like there’s no cost. You still need a stack for every green thread, just like you need one for every normal thread. I think it’s worth it to figure out a good system for stackless async. Something like Kotlin is about as good as it gets. Rust is getting there, despite all the ownership issues, which would exist in green threads too.
Re:Python has had async for 10 years – why isn't it more pop... by jacquesm on Tuesday September 02, 2025 @08:16PM (#45110805)
There are much better solutions for the same problems, but not in Python. If you really need such high throughput you'd move to Go, the JVM or Erlang/Elixer depending on the kind of workload you have rather than to much around with Python on something that it clearly was never intended to do in the first place. It is amazing they got it to work as well as it does but the impedance mismatch is pretty clear and it will never feel natural.
Re:Python has had async for 10 years – why isn't it more pop... by ch4s3 on Tuesday September 02, 2025 @10:47PM (#45111785)
Elixir is a really nice replacement for a lot of places where you could you python but don't absolutely have to, particularly anything web related. You get a lot more out of the same machine with code that's similarly readable for building HTTP APIs.
Re:Python has had async for 10 years – why isn't it more pop... by a-dub on Tuesday September 02, 2025 @11:07PM (#45111877)
also most python usecases that are in the realm of things like high performance concurrent request servicing push it down into libraries that i think are often tied to a native network request processing core. (gunicorn, grpc, etc)

python is kind of a slow choice for that sort of thing regardless and i don't think the complexity of async is all that justified for most usecases.

i still maintain my position that a good computer system should let you write logic synchronously and the system will figure out how to do things concurrently with high performance. (although getting this right would be very hard!)

Re:Python has had async for 10 years – why isn't it more pop... by wodenokoto on Tuesday September 02, 2025 @11:11PM (#45111901)
It might have been too little but it wasn’t too late.

Generations of programmers have given up on downloading data async in their Python scripts and just gone to bash and added a & at the end of a curl call inside a loop.

Re:Python has had async for 10 years – why isn't it more pop... by cookiengineer on Wednesday September 03, 2025 @03:00AM (#45113010)
I agree with you, I think. It's hard to figure out your own position when it comes to multithreading and multitasking APIs.

To me, Go is really well designed when it comes to multithreading because it is built upon a mutual contract where it will break easily and at compile time when you mess up the contract between the scheduling thread and the sub threads.

But, for the love of Go, I have no idea who the person was that decided that the map data type has to be not threadsafe. Once you start scaling / rewriting your code to use multiple goroutines, it's like you're being thrown in the cold water without having learnt to swim before.

Mutexes are a real pain to use in Go, and they could have been avoided if the language just decided to make read/write access threadsafe for at least maps that are known to be accessed from different threads.

I get the performance aspect of that decision, but man, this is so painful because you always have to rewrite large parts of your data structures everywhere, and abstract the former maps away into a struct type that manages the mutexes, which in return feels so dirty and unclean as a provided solution.

For production systems I just use haxmap from the start, because I know its limitations (of hashes of keys due to atomics), because that is way easier to handle than forgetting about mutexes somewhere down the codebase when you are still before the optimization phase of development.

Re:Python has had async for 10 years – why isn't it more pop... by pjmlp on Wednesday September 03, 2025 @03:32AM (#45113188)
Java has had green threads since day one, most vendors ended up going red threads full way, and now we're back into green and red world.

The main difference being that now both models are simultaneously supported instead of being an implementation detail of each JVM.