3 ms·
My first ever EM showed me this piece ~10 years ago, and I still think about it a lot. One pattern I've adopted is to keep as much code to be synchronous as pos
by frankfrank13 4mo ago
My first ever EM showed me this piece ~10 years ago, and I still think about it a lot. One pattern I've adopted is to keep as much code to be synchronous as possible. On larger teams, especially when the slop-cannon is really going, I can at least depend on codeowners to tag me if someone tries to convert something to async (eg. adding a DB call somewhere), because they chain of things that need to be converted to async is so long. Then I can jump in and say "this entire chain of code is sync, if you want a DB call, do it somewhere else"
- gordonhart 4mo agoFor Python backends I've seen good success with just making it company policy that everything is synchronous (normal-colored) and bypassing the developer overhead from async/await. Cooperative multitasking is a pain because, well, it requires cooperation. You can go pretty far by just adding more threads, processes, and replicas before it's worth the overhead.
- graemep 4mo agoI just do not want to do async in Python. If you need async its questionable whether Python is a good choice at all, and if you use Python maybe look at another solution if at all possible (even using more processes and throwing hardware at it).
- seabrookmx 4mo agoYou not only leave performance on the table (which depending on your use case/environment, may not matter if you can just throw more threads at it) but also some developer ergonomics. asyncio.gather is a lot less code than having to manage a thread pool or something like Celery with all it's underlying infrastructure. If you're in an ecosystem where a lot of the async boilerplate is free/cheap (ex: FastAPI) then the developer overhead of sprinkling awaits on your I/O bound calls is pretty low IMO.
- bigstrat2003 4mo agoPerformance aside (which I would argue is premature optimization, as most programs will not feel the theoretical overhead of threads), async is a bad approach for developer ergonomics. Threads are so much easier to work with and reason about than async. There are reasons to use async (like if you're in the rare case when thread overhead is noticeable), but developer ergonomics are absolutely not a reason.
- seabrookmx 4mo agoSay I need the results from two expensive REST API calls, so I want to run them concurrently. Managing a thread pool you find a _better_ experience than one, two = await asyncio.gather(callOne(), callTwo()) ?
- wtetzner 4mo agoDoesn't Python support futures? with ThreadPoolExecutor() as executor: one, two = executor.map(lambda f: f(), [callOne, callTwo]) I'm sure you could write a nicer helper function that's more similar to gather as well.
- seabrookmx 4mo agoSure, in a web server context you'd probably want to instantiate that executor globally and re-use it, Then you could write helper functions around that. But it's still considerably more code and legwork than the async alternative, while also being slower and using more memory if you care about those things.
- ian_j_butler 4mo ago> something like Celery with all it's underlying infrastructure. Unpopular opinion, but combining this with the other "no thanks" sentiments in this subthread is the right answer. Your app is so complicated you need async? Then it's complicated enough that you can benefit from infrastructure. I don't want to watch coworkers try to badly rebuild message queue or scheduling semantics in an application code base. Just use infrastructure that's made by people who know what they are doing. That was problematic in 2015, but in 2026 it's a bit of docker, and it's not just about web/microservices. Very easy for sufficiently complex apps to simply leverage a local sandbox of celery, redis, graphdb's and whatever. Stand-alone is overrated since we don't have to do it anymore.. app devs should get more comfortable working with ensembles like this so they have access to best-in-class solutions. You don't like infrastructure AND have such a need for performance AND don't want threads or multiprocess? Consider using another language. Async is mostly a solution in search of a problem, and the enduring popularity of TFA goes to show this has been the right conclusion for ~10 years.