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.
| Metrik | Ergebnis |
|---|---|
| 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).
| Metrik | Flask (Lambda) | Quart (ASGI) | Änderung |
|---|---|---|---|
| Infrastrukturkosten | ~$1.000/Tag | ~$50/Tag | −90% |
| Durchsatz | ~150 req/s | 300+ req/s | 2x |
| Fehler zu Spitzenzeiten | Ausgangswert | −95% | −95% |
| Latenz | Ausgangswert | −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
requestsdurchaiohttpfü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.
| Metrik | Threads | Asyncio | Änderung |
|---|---|---|---|
| Latenz | Ausgangswert | −40% | −40% |
| RAM-Verbrauch | 18 GB (Hunderte von Threads) | Deutlich weniger | Erhebliche 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.
| Metrik | Flask | Quart | Änderung |
|---|---|---|---|
| Antwortzeit (Beispiel) | 42 ms | 8 ms | −81% |
| Bugs nach Migration | — | 2 | Minimal |
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.
| Test | Standard-asyncio | uvloop | Verbesserung |
|---|---|---|---|
| 10K Anfragen, 50 VU (lokal) | 515 req/s | 565 req/s | +10% |
| 5 Min, 100 VU (Azure) | 1.898 req/s | 1.961 req/s | +3% |
| 500 VU (lokal) | 720 req/s | 772 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:
| Modell | Zeit | Durchsatz | Fehler |
|---|---|---|---|
| Synchron | ~1.800 s | ~11 KB/s | — |
| Threads (100) | ~85 s | ~238 KB/s | Gering |
| Asyncio | 14 s | 1.435 KB/s | 0,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:
| Implementierung | 1 KiB (req/s) | 100 KiB Durchsatz |
|---|---|---|
| uvloop | 105.459 | 2,3 GiB/s |
| Go | 103.264 | — |
| Standard-asyncio | 41.420 | — |
| Node.js | 44.055 | — |
HTTP-Server (300 gleichzeitige):
| Implementierung | 1 KiB (req/s) |
|---|---|
| uvloop + httptools | 37.866 |
| Node.js | Niedriger |
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
| Bibliothek | req/s (gleichzeitig) | Typ |
|---|---|---|
| aiohttp | 241+ | Async |
| HTTPX (async) | ~160 | Async |
| Requests | ~24 | Sync |
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):
| Framework | Typ | req/s | P99-Latenz |
|---|---|---|---|
| Gunicorn + Meinheld/Bottle | Sync | 5.780 | 32 ms |
| Gunicorn + Meinheld/Falcon | Sync | 5.589 | 31 ms |
| Uvicorn + Starlette | Async | 4.952 | 75 ms |
| Sanic | Async | 4.687 | 85 ms |
| AIOHTTP | Async | 4.501 | 76 ms |
Ergebnis: Synchrone Frameworks mit C-Servern zeigten höheren Durchsatz und 2–3x bessere Tail-Latenz (P99).
Warum hat Async verloren?
Gründe:
- Eine einzelne SQL-Abfrage pro HTTP-Anfrage — zu wenig I/O, als dass Coroutine-Nebenläufigkeit einen Effekt hätte.
- Kooperatives Multitasking mit CPU-Arbeit zwischen Anfragen erzeugt eine „unfaire” CPU-Zeitverteilung — lange Berechnungen blockieren die Event-Loop für alle.
- 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:
| Framework | Typ | req/s (JSON) |
|---|---|---|
| Uvicorn (raw) | Async ASGI | Höchster unter Python |
| Starlette | Async ASGI | ~20.000–25.000 |
| FastAPI | Async 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
| Fall | Sync → Async | Bedingung |
|---|---|---|
| Duolingo (Produktion) | +40% Durchsatz, −30% Kosten | Microservices, I/O |
| Super.com (Produktion) | 2x Durchsatz, −90% Kosten | 40+ API-Aufrufe pro Anfrage |
| Feature Store (Produktion) | −40% Latenz | Migration von Threads zu asyncio |
| Talk Python (Produktion) | −81% Latenz | Flask → Quart |
| I/O-gebunden (10K URLs) | 130x schneller | Reines I/O, massive Nebenläufigkeit |
| aiohttp vs. requests | 10x schneller | Gleichzeitige HTTP-Anfragen |
| uvloop vs. Standard | 2,5x schneller | TCP-Echo, HTTP |
| TechEmpower JSON | 3–5x | FastAPI/Starlette vs. Flask/Django |
| Einfaches CRUD (1 SQL) | Sync ist schneller | Cal Paterson: P99 2–3x schlechter für Async |
| CPU-gebunden | Kein 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:
| Eigenschaft | Python | PHP |
|---|---|---|
| Interpretiert | Ja | Ja |
| GIL / Single-Threaded | GIL | Single-Threaded |
| Dominantes Modell | Sync (Django, Flask) | Sync (FPM) |
| Async-Laufzeit | asyncio + uvloop | Swoole / True Async |
| Async-Framework | FastAPI, Starlette | Hyperf |
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
- Duolingo: How We Started Our Async Python Migration (2025)
- Super.com: Quart ASGI, 90% Kostenreduktion
- Instagram: asyncio adoption at scale (PyCon Taiwan 2018)
- Feature Store: Multithreading to Asyncio
- Talk Python: Flask → Quart rewrite
- Microsoft Azure: uvloop als Standard (2025)
Benchmarks
- Cal Paterson: Async Python is not faster
- Python Concurrency Model Comparison (2025)
- HTTPX vs Requests vs AIOHTTP (Oxylabs)
- uvloop: Blazing fast Python networking (MagicStack)
- TechEmpower Framework Benchmarks