Dart auf dem Server: Warum es unter Produktionslast zusammenbrach
Ein SaaS-Entwickler tauschte Node.js gegen Dart aus, um den Speicherverbrauch zu senken. Erwartungen: 10 MB Start vs. 80 MB, AOT-Kompilierung und statische Typisierung. Realität: zwei Wochen Entwicklungszeit, ein selbstgebauter Framework und Benchmarks mit schlechterer Performance. Lehre: Immer rohe Benchmarks mit Produktionslasten durchführen, bevor man migriert.
Der Auth-Service (OAuth2, Redis-ORM) diente als Testumgebung. Node.js erreichte 500 MB Peak, gab Speicher aber frei. Hunderte Instanzen mit 80 MB Start waren das Kernproblem.
Ökosystem: Keine Backend-Tools in Sicht
Dart ist für Flutter gebaut. Keine NestJS-Äquivalente, wenige Redis-Clients erreichen die Qualität von ioredis. Shelf ist ein simpler Router, Serverpod zielt auf Full-Stack-Flutter-Apps ab.
Musste ein Framework von Grund auf bauen:
- Baum basierte DI wie Angular.
- Request-Scoping via Zone.
- CLI mit Codegen für AOT.
Portiert ts-oauth2-server und ioredis (4.500 Zeilen Dart vs. 23.500 TS). KI hat es übernommen, aber mit Kosten: experimenteller Flag --enable-experiment=enhanced-parts, part 'file.g.dart' überall, Commit-Sheets oder CI-Generierung.
Reflection ist bei AOT weg. Type ist ein Stub, keine statischen Methodenaufrufe. DI ohne Mirrors braucht CLI in JIT → Mirrors → Codegen. In TS/Java/C# sind es drei Zeilen Reflection.
Sprache: Schöne Syntax, furchtbar für Metaprogramming
Logische Syntax, Compile-Time-Fehler. Aber kein for...in auf Objekten, keine Reflection. Codegen ist ein Albtraum: .g.dart-Referenzen vermüllen Quell-Dateien.
KI hat ioredis mechanisch portiert. Ergebnis: +5% RPS über dem besten pub.dev-Client. RIP Backend-Ökosystem – niemand schreibt Server-Code in Dart.
Benchmarks: Latenz und Speicher machen es zunichte
Szenario: 3 Endpoints, Postgres, Redis. Rohes HTTP, keine Frameworks. 100m CPU, 500 VUS.
| Metrik | Dart AOT | Node.js | Go |
|---------|----------|---------|----|
| RSS Start | 3 MB | 18 MB | - |
| p95 Latenz | 9,5 s | 5 s | 2,9 s |
| RPS | 2x schlechter als Node | - | Bestes insgesamt |
| Peak RSS | 39-47 MB | 37 MB | - |
Dart:
- Gibt Speicher nicht an OS zurück (>5% nach Peak).
- GC unter Druck: Pausen für 60fps (Flutter) optimiert, nicht RSS für K8s.
- Unter Throttling auf 47 MB aufgebläht; Node schrumpft.
GC-Flags (--dontneed_on_sweep, --use_compactor) halfen nicht. Von Design: VM für Mobile. K8s sieht 40 MB/Pod konstant, HPA kann Nodes nicht eng packen. Startvorteil aufgefressen durch Überprovisionierung.
Auf Cloud Run: Dart kostet mehr als Node – langsamer + hält Speicher fest.
Wichtige Erkenntnisse:
- p95 Latenz 9,5 s vs. 5 s Node = Produktionsfehler.
- Speicher nicht freigegeben: Skalierung teurer.
- Ökosystem tot außerhalb Flutter.
- Benchmarks im Repo: K8s-Manifeste, CPU-Profile, Dockerfiles.
Urteil: Darts Nische ist nur Flutter
Zwei Wochen verloren für Framework, Ports, Tests. Dart glänzt bei einfachem Code, aber serverseitig ein Reinfall. Keine Reflection, VM nicht cloud-tauglich, Codegen-Hölle. Offizielle "skalierbare APIs für Cloud Run"-Versprechen enttäuscht.
Go abgelehnt wegen err != nil und context.Context. Node.js siegt: gibt Speicher frei, bessere Latenz.
— Editorial Team
Noch keine Kommentare.