Live data from Hacker News

Python has had async for 10 years – why isn't it more popular?

tonybaloney.github.io

101–110 of 305 posts

Re: Python has had async for 10 years – why isn't it more popular?

#101
post #32

idk stackless dates back to 2005 at least, most likely earlier. greenlet which is sort of minimal stackless .. before 2008 pycoev which is on one hand greenlets without memmove()s, on the other hand sort of io-scheduled m:n threading I wrote myself in 2009. so, at least idk, 20 years? It was first needed. Then 10 years passed, people got around to pushing it through the process aaand by the time it was done it was al…

I never understood why stackless wasn't more popular. It was rather nice, clean and performant (well, it's still python but it provide(d) proper concurrency)

It was memmove() on each task switch. So you could forget about d-cache. And that killed performance on anything but benchmarks.

Re: Python has had async for 10 years – why isn't it more popular?

#102
post #73
post #70

I learned about the concept of async/await from JS and back then was really amazed by the elegance of it. By now, the downsides are well-known, but I think Python's implementation did a few things that made it particularly unpleasant to use. There is the usual "colored functions" problem. Python has that too, but on steroids: There are sync and async functions, but then some of the sync functions can only be called f…

> some of the sync functions can only be called from an async function, because they expect an event loop to be present I recognise that this situation is possible, but I don't think I've ever seen it happen. Can you give an example?

Everything that directly interacts with an event loop object and calls methods such as loop.call_soon() [1].

This is used by most of asyncio's synchronization primitives, e.g. async.Queue.

A consequence is that you cannot use asyncio Queues to pass messages or work items between async functions and worker threads. (And of course you can't use regular blocking queues either, because they would block).

The only solution is to build your own ad-hoc system using loop.call_soon_threadsafe() or use third-party libs like Janus[2].

[1] https://github.com/python/cpython/blob/e4e2390a64593b33d6556...

[2] https://github.com/aio-libs/janus

Re: Python has had async for 10 years – why isn't it more popular?

#103
post #27

With the newest Python, I can use no-gil, so my threads automatically use multiple cores. With asyncio, even under no-gil, unless I use a base layer that offers parallelism, I am stuck to a single core by default, which doesn't make any sense in a multicore world. In contrast, with Rust's async, there is no such limitation. The traditional argument against the above assertion has been that asyncio is good for I/O wor…

You should look into the various Pool classes. Back when asyncio came about, I did a lot of experimenting with various multi-core approaches: https://github.com/rcarmo/newsfeed-corpus

[deleted]

Re: Python has had async for 10 years – why isn't it more popular?

#104
post #61

Not too long ago, I read a comment on HN that suggested, due to Python's support for free-threading, async in Python will no longer be needed and will lose out to free-threading due to it's use of "colored" functions. Which seems to align with where this author ends up: > Because parallelism in Python using threads has always been so limited, the APIs in the standard library are quite rudimentary. I think there is an…

async was the wrong solution to the right problem - improving general performance. Free threading is the prize in an increasingly multi-core CPU world.

Re: Python has had async for 10 years – why isn't it more popular?

#105

I suppose my negative experiences with async fall under #3, that it is hard to maintain two APIs. One of the most memorable "real software engineering" bugs of my career involved async Python. I was maintaining a FastAPI server which was consistently leaking file descriptors when making any outgoing HTTP requests due to failing to close the socket. This manifested in a few ways: once the server ran out of available f…

> it is hard to maintain two APIs. This point doesn't get enough coverage. When I saw async coming into Python and C# (the two ecosystems I was watching most closely at the time) I found it depressing just how much work was going into it that could have been productively expended elsewhere if they'd have gone with blocking calls to green threads instead. To add insult to injury, when implementing async it seems inevi…

> I don't use it much anymore, but Twisted Matrix was (is?) great at this.

You must be an experienced developer to write maintenable code with Twisted, otherwise, when the codebase increase a little, it will quickly become a bunch of spaghetti code.

Re: Python has had async for 10 years – why isn't it more popular?

#106

I went through a phase of writing asyncio servers for my side projects. Probably the most fun I had was writing things that were responsive in complex ways, such as a websockets server that was also listening on message queues or on a TCP connection to a Denon HEOS music player. Eventually I wrote an "image sorter" that I found was hanging up when the browser was trying to download images in parallel, the image servi…

That's the main problem with evented servers in general isn't it? If any one of your workloads is cpu-intensive, it has the potential to block the serving of everything else on the same thread, so requests that should always be snappy can end up taking randomly long times in practice. Basically if you have any cpu-heavy work, it shouldn't go in that same server.

My system is written in Python because it is supported by a number of batch jobs that use code from SBERT, scikit-learn, numpy and such. Currently the server doesn't do any complex calculations but under asyncio it was a strict no-no. Mostly it does database queries and formats HTML responses but it seems like that is still too much CPU.

My take on gunicorn is that it doesn't need any tuning or care to handle anything up to the large workgroup size other than maybe "buy some more RAM" -- and now if I want to do some inference in the server or use pandas to generate a report I can do it.

If I had to go bigger I probably wouldn't be using Python in the server and would have to face up to either dual language or doing the ML work in a different way. I'm a little intimidated about being on the public web in 2025 though with all the bad webcrawlers. Young 'uns just never learned everything that webcrawler authors knew in 1999. In 2010 there were just two bad Chinese webcrawlers that never sent a lick of traffic to anglophone sites, but now there are new bad webcrawlers every day it seems.

Re: Python has had async for 10 years – why isn't it more popular?

#107
post #101

Earlier quoted context omitted.

I never understood why stackless wasn't more popular. It was rather nice, clean and performant (well, it's still python but it provide(d) proper concurrency)

It was memmove() on each task switch. So you could forget about d-cache. And that killed performance on anything but benchmarks.

Also caused subtle bugs. I once had to debug a crash in C++ code that turned out to be due to Stackless Python corrupting stack state on Windows. OutputDebugString() would intermittently crash because Stackless had temporarily copied out part of the stack and corrupted the thread's structured exception handling chain. This wasn't obvious because this occurred in a very deep call stack with Stackless much higher up, and it only made sense if you knew that OutputDebugString() is implemented internally by throwing a continuable exception.

The more significant problem was that Stackless was a separate distribution. Every time CPython updated, there would be a delay until Stackless updated, and tooling like Python IDEs varied in whether they supported Stackless.

Re: Python has had async for 10 years – why isn't it more popular?

#108
post #59

Earlier quoted context omitted.

> 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 do…

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 wil…

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[1].

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.

[1]: 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 popular?

#109
Because I don't need it.

When I need to do concurrent stuff I either use fork to multiprocess or use the threading library, no import necessary, couple of lines of code, no need to make specialized code with await keywords and stuff.

This line made me question myself though:

"Then Flask is and probably always will be synchronous (Quart is an async alternative with similar APIs)."

I use flask, and I literally spent the last hour questioning whether I was an idiot and needed to dm my previous clients asking them to fix my code. I'm wondering how my apps passed stress tests of thousands of concurrent users, maybe I did the tests wrong?

Chatgpt says

"s flask asynchronous? ChatGPT said:

Flask itself is not asynchronous. It is a WSGI-based framework, which means it is synchronous by design — it handles one request at a time per worker. Each request is processed sequentially, and concurrency is typically achieved by running multiple worker processes"

Oh shit, I didn't use gunicorn, I just run the python script raw. I'm an idiot. Let's write a test server that sleeps for 1 second before responding to a request:

" import flask import requests import time app = flask.Flask("test")

@app.route("/") def hi(): time.sleep(1) #requests.get("https://google.com") return "Hello, World!"

app.run("0.0.0.0",8088) "

This should block for like 25ms, if 50 concurrent users ask for this resource, there will be an average 500ms of extra latency!

And a Test client that does 50 calls at once, will it take 50 seconds?:

"import threading import requests

URL = "http://127.0.0.1:8088/"

def make_request(i): try: print("req") response = requests.get(URL) print("res") except: print("fail")

threads = []

for i in range(5): t = threading.Thread(target=make_request, args=(i,)) threads.append(t) t.start()

for t in threads: t.join()

print("All requests completed")

"

Then we run with time binary in linux:

>time python3 client.py

All requests completed

real 0m1.216s user 0m0.203s sys 0m0.039s

Ok, turn off the alarms, Flask is fine.

I'm not sure what's going on with async, but the only experience I had with it was a junior dev that came from writing horrible node apps with react and nest (his frontend connected to a supabase db directly with credentials exposed, even if there was a node backend).

He wanted to pivot to python because that's what I used and I had good results, so he installed Quartz instead of Flask, and he was writing Node like code in python, and it was of course a mess.

Not saying that it's always going to be a mess, but you are better off learning the native way of a language instead of trying to shoehorn other abstractions and claiming that the way it is done in python is inefficient, it's one of the most popular languages in the world, these are massively used libraries, it's unlikely that "something is terribly wrong". It's more of a meme that python is slow.

What async is, is an alternative and supposedly cleaner abstraction to do multithreading. What ends up happening is that people use it without understanding multithreading and operating systems in general, they just think that they need to use it to get parallelism.

There's 15 solutions to do parallelism, 1 is the native, vanilla solution (threading library), then there's 3 additional experimental ways in the standard library or futures library, and 11 solutions that you need to pip install. Newbies ask chatgpt or see a stackoverflow thread (or come from node), and they have a 1 in 15 chance of using the regular solution that newbies should be using, because they can't distinguish the wheat from the chaffe.

OP might have suffered from this and even believed that this 15th "async" way to do concurrency was the only way, and is judging python's concurrency by this feature. OP maybe believes that python is just now getting multithreading support? That we are all cavemen running toy applications that server 2 or 3 users? Word to the wise, focus on features that have existed on early versions like python2 BEFORE you focus on features that are being introduced in the later versions like 3.14, this in general, you should first learn how a UNIX machine from the 90s did its thing before you learn the kubernetes spark majiggy

Re: Python has had async for 10 years – why isn't it more popular?

#110
A little history...

During development, asyncio was called tulip. A quick search turns up this talk by Guido:

https://www.youtube.com/watch?v=aurOB4qYuFM

I seem to recall that Guido was in touch with the author of Twisted at the time, so design ideas from that project may have helped shape asyncio.

https://twisted.org/

Before asyncio, Python had asyncore, a minimal event loop/callback module. I think it was was introduced in Python 1.5.2, and remained part of the standard library until 3.12.

https://docs.python.org/3.11/library/asyncore.html

https://docs.python.org/3.11/library/asynchat.html

Post reply on HN