Python asyncio in der Praxis: Reale Messungen

Python ist die Sprache, die PHP in Bezug auf das Ausführungsmodell am ähnlichsten ist: interpretiert, single-threaded (GIL), mit einer Dominanz synchroner Frameworks. Der Übergang von synchronem Python (Flask, Django + Gunicorn) zu asynchronem (FastAPI, aiohttp, Starlette + Uvicorn) ist eine exakte Analogie zum Übergang von PHP-FPM zu einer Coroutine-basierten Laufzeitumgebung.

Nachfolgend eine Sammlung von Produktionsfällen, unabhängigen Benchmarks und Messungen.


1. Produktion: Duolingo — Migration zu Async Python (+40% Durchsatz)

Duolingo ist die größte Sprachlernplattform (500M+ Nutzer). Das Backend ist in Python geschrieben.

2025 begann das Team eine systematische Migration der Dienste von synchronem Python zu async.

MetrikErgebnis
Durchsatz pro Instanz+40%
AWS-EC2-Kosteneinsparung~30% pro migriertem Dienst

Die Autoren merken an, dass nach dem Aufbau der Async-Infrastruktur die Migration einzelner Dienste sich als „ziemlich unkompliziert" herausstellte.

Quelle: How We Started Our Async Python Migration (Duolingo Blog, 2025)


2. Produktion: Super.com — 90% Kostenreduktion

Super.com (ehemals Snaptravel) ist ein Hotel-Such- und Rabattdienst. Ihre Suchmaschine verarbeitet 1.000+ req/s, nimmt 1 TB+ Daten pro Tag auf und wickelt täglich $1M+ Umsatz ab.

Zentrale Workload-Eigenschaft: Jede Anfrage führt 40+ Netzwerkaufrufe an Drittanbieter-APIs durch. Dies ist ein reines I/O-gebundenes Profil — ein idealer Kandidat für Coroutinen.

Das Team migrierte von Flask (synchron, AWS Lambda) zu Quart (ASGI, EC2).

MetrikFlask (Lambda)Quart (ASGI)Änderung
Infrastrukturkosten~$1.000/Tag~$50/Tag−90%
Durchsatz~150 req/s300+ req/s2x
Fehler zu SpitzenzeitenAusgangswert−95%−95%
LatenzAusgangswert−50%2x schneller

Einsparungen von $950/Tag × 365 = ~$350.000/Jahr bei einem einzelnen Dienst.

Quelle: How we optimized service performance using Quart ASGI and reduced costs by 90% (Super.com, Medium)


3. Produktion: Instagram — asyncio im Maßstab von 500M DAU

Instagram bedient 500+ Millionen täglich aktive Nutzer auf einem Django-Backend.

Jimmy Lai (Instagram-Ingenieur) beschrieb die Migration zu asyncio in einem Vortrag auf der PyCon Taiwan 2018:

  • Ersetzung von requests durch aiohttp für HTTP-Aufrufe
  • Migration des internen RPC zu asyncio
  • Erreichte API-Leistungsverbesserung und reduzierte CPU-Leerlaufzeit

Herausforderungen: Hoher CPU-Overhead von asyncio im Instagram-Maßstab, die Notwendigkeit einer automatisierten Erkennung blockierender Aufrufe durch statische Code-Analyse.

Quelle: The journey of asyncio adoption in Instagram (PyCon Taiwan 2018)


4. Produktion: Feature Store — Von Threads zu asyncio (−40% Latenz)

Der Feature-Store-Dienst migrierte von Python-Multithreading zu asyncio.

MetrikThreadsAsyncioÄnderung
LatenzAusgangswert−40%−40%
RAM-Verbrauch18 GB (Hunderte von Threads)Deutlich wenigerErhebliche Reduktion

Die Migration wurde in drei Phasen mit 50/50-Produktions-Traffic-Aufteilung zur Validierung durchgeführt.

Quelle: How We Migrated from Python Multithreading to Asyncio (Medium)


5. Produktion: Talk Python — Flask zu Quart (−81% Latenz)

Talk Python ist einer der größten Python-Podcasts und Lernplattformen. Der Autor (Michael Kennedy) schrieb die Seite von Flask (synchron) zu Quart (asynchrones Flask) um.

MetrikFlaskQuartÄnderung
Antwortzeit (Beispiel)42 ms8 ms−81%
Bugs nach Migration2Minimal

Der Autor merkt an: Beim Lasttest unterschieden sich die maximalen req/s nur unwesentlich, da MongoDB-Abfragen <1 ms dauerten. Der Gewinn zeigt sich bei gleichzeitiger Anfrageverarbeitung — wenn mehrere Clients gleichzeitig auf den Server zugreifen.

Quelle: Talk Python rewritten in Quart (async Flask)


6. Microsoft Azure Functions — uvloop als Standard

Microsoft hat uvloop — eine schnelle Event-Loop basierend auf libuv — als Standard für Azure Functions auf Python 3.13+ integriert.

TestStandard-asynciouvloopVerbesserung
10K Anfragen, 50 VU (lokal)515 req/s565 req/s+10%
5 Min, 100 VU (Azure)1.898 req/s1.961 req/s+3%
500 VU (lokal)720 req/s772 req/s+7%

Die Standard-Event-Loop bei 500 VU zeigte ~2% Anfrageverluste. uvloop — null Fehler.

Quelle: Faster Python on Azure Functions with uvloop (Microsoft, 2025)


7. Benchmark: I/O-gebundene Aufgaben — asyncio 130x schneller

Direkter Vergleich von Nebenläufigkeitsmodellen bei einer Aufgabe zum Herunterladen von 10.000 URLs:

ModellZeitDurchsatzFehler
Synchron~1.800 s~11 KB/s
Threads (100)~85 s~238 KB/sGering
Asyncio14 s1.435 KB/s0,06%

Asyncio: 130x schneller als synchroner Code, 6x schneller als Threads.

Für CPU-gebundene Aufgaben bietet asyncio keinen Vorteil (identische Zeit, +44% Speicherverbrauch).

Quelle: Python Concurrency Model Comparison (Medium, 2025)


8. Benchmark: uvloop — Schneller als Go und Node.js

uvloop ist ein Drop-in-Ersatz für die Standard-asyncio-Event-Loop, geschrieben in Cython auf Basis von libuv (derselben Bibliothek, die Node.js zugrunde liegt).

TCP-Echo-Server:

Implementierung1 KiB (req/s)100 KiB Durchsatz
uvloop105.4592,3 GiB/s
Go103.264
Standard-asyncio41.420
Node.js44.055

HTTP-Server (300 gleichzeitige):

Implementierung1 KiB (req/s)
uvloop + httptools37.866
Node.jsNiedriger

uvloop: 2,5x schneller als Standard-asyncio, 2x schneller als Node.js, auf Augenhöhe mit Go.

Quelle: uvloop: Blazing fast Python networking (MagicStack)


9. Benchmark: aiohttp vs. requests — 10x bei gleichzeitigen Anfragen

Bibliothekreq/s (gleichzeitig)Typ
aiohttp241+Async
HTTPX (async)~160Async
Requests~24Sync

aiohttp: 10x schneller als Requests bei gleichzeitigen HTTP-Anfragen.

Quelle: HTTPX vs Requests vs AIOHTTP (Oxylabs)


10. Gegenargument: Cal Paterson — „Async Python ist nicht schneller"

Es ist wichtig, auch Gegenargumente darzustellen. Cal Paterson führte einen gründlichen Benchmark mit einer echten Datenbank durch (PostgreSQL, zufällige Zeilenauswahl + JSON):

FrameworkTypreq/sP99-Latenz
Gunicorn + Meinheld/BottleSync5.78032 ms
Gunicorn + Meinheld/FalconSync5.58931 ms
Uvicorn + StarletteAsync4.95275 ms
SanicAsync4.68785 ms
AIOHTTPAsync4.50176 ms

Ergebnis: Synchrone Frameworks mit C-Servern zeigten höheren Durchsatz und 2–3x bessere Tail-Latenz (P99).

Warum hat Async verloren?

Gründe:

  1. Eine einzelne SQL-Abfrage pro HTTP-Anfrage — zu wenig I/O, als dass Coroutine-Nebenläufigkeit einen Effekt hätte.
  2. Kooperatives Multitasking mit CPU-Arbeit zwischen Anfragen erzeugt eine „unfaire" CPU-Zeitverteilung — lange Berechnungen blockieren die Event-Loop für alle.
  3. asyncio-Overhead (Standard-Event-Loop in Python) ist vergleichbar mit dem Gewinn durch nicht-blockierendes I/O, wenn I/O minimal ist.

Wann Async tatsächlich hilft

Patersons Benchmark testet das einfachste Szenario (1 SQL-Abfrage). Wie die obigen Produktionsfälle zeigen, bietet async einen dramatischen Gewinn, wenn:

  • Es viele DB- / externe API-Abfragen gibt (Super.com: 40+ Aufrufe pro Anfrage)
  • Die Nebenläufigkeit hoch ist (Tausende gleichzeitige Verbindungen)
  • I/O dominiert über CPU (Duolingo, Appwrite)

Dies stimmt mit der Theorie überein: Je höher der Blockierungskoeffizient (T_io/T_cpu), desto größer der Nutzen von Coroutinen. Bei 1 SQL-Abfrage × 2 ms ist der Koeffizient zu niedrig.

Quelle: Async Python is not faster (Cal Paterson)


11. TechEmpower: Python-Frameworks

Ungefähre Ergebnisse aus TechEmpower Round 22:

FrameworkTypreq/s (JSON)
Uvicorn (raw)Async ASGIHöchster unter Python
StarletteAsync ASGI~20.000–25.000
FastAPIAsync ASGI~15.000–22.000
Flask (Gunicorn)Sync WSGI~4.000–6.000
Django (Gunicorn)Sync WSGI~2.000–4.000

Async-Frameworks: 3–5x schneller als synchrone im JSON-Test.

Quelle: TechEmpower Framework Benchmarks


Zusammenfassung: Was die Python-Daten zeigen

FallSync → AsyncBedingung
Duolingo (Produktion)+40% Durchsatz, −30% KostenMicroservices, I/O
Super.com (Produktion)2x Durchsatz, −90% Kosten40+ API-Aufrufe pro Anfrage
Feature Store (Produktion)−40% LatenzMigration von Threads zu asyncio
Talk Python (Produktion)−81% LatenzFlask → Quart
I/O-gebunden (10K URLs)130x schnellerReines I/O, massive Nebenläufigkeit
aiohttp vs. requests10x schnellerGleichzeitige HTTP-Anfragen
uvloop vs. Standard2,5x schnellerTCP-Echo, HTTP
TechEmpower JSON3–5xFastAPI/Starlette vs. Flask/Django
Einfaches CRUD (1 SQL)Sync ist schnellerCal Paterson: P99 2–3x schlechter für Async
CPU-gebundenKein Unterschied+44% Speicher, 0% Gewinn

Zentrale Erkenntnis

Async Python bietet maximalen Nutzen bei einem hohen Blockierungskoeffizienten: wenn die I/O-Zeit die CPU-Zeit deutlich übersteigt. Bei 40+ Netzwerkaufrufen (Super.com) — 90% Kostenersparnis. Bei 1 SQL-Abfrage (Cal Paterson) — async ist langsamer.

Dies bestätigt die Formel aus Effizienz I/O-gebundener Aufgaben: Gewinn ≈ 1 + T_io/T_cpu. Wenn T_io >> T_cpu — zehn- bis hundertfach. Wenn T_io ≈ T_cpu — minimal oder null.


Verbindung zu PHP und True Async

Python und PHP befinden sich in einer ähnlichen Situation:

EigenschaftPythonPHP
InterpretiertJaJa
GIL / Single-ThreadedGILSingle-Threaded
Dominantes ModellSync (Django, Flask)Sync (FPM)
Async-Laufzeitasyncio + uvloopSwoole / True Async
Async-FrameworkFastAPI, StarletteHyperf

Die Python-Daten zeigen, dass der Übergang zu Coroutinen in einer single-threaded interpretierten Sprache funktioniert. Das Ausmaß des Gewinns wird durch das Workload-Profil bestimmt, nicht durch die Sprache.


Referenzen

Produktionsfälle

Benchmarks

Coroutinen vs. Threads