Vibe Coding: Die versteckten Kosten von KI gebauten Architekturen

Es gibt ein neues Muster in der Softwareentwicklung. Jemand hat eine Idee, startet ChatGPT oder Claude und beginnt zu bauen. Die KI schreibt den Code. Der Prototyp funktioniert. Der Gründer ist begeistert. Sechs Monate später brennt das System, die Datenbank schmilzt und ein richtiger Ingenieur wird hinzugezogen, um die schlechte Nachricht zu überbringen: Das Ganze muss von Grund auf neu gebaut werden. Ich nenne das Vibe Coding. Software bauen basierend auf Vibes statt architektonischem Verständnis. Die KI kann syntaktisch korrekten Code schreiben, aber sie kann nicht die strategischen Entscheidungen treffen, die bestimmen ob ein System skaliert, performt oder überhaupt den Kontakt mit echten Nutzern überlebt.

Es gibt ein neues Muster in der Softwareentwicklung. Jemand hat eine Idee, startet ChatGPT oder Claude und beginnt zu bauen. Die KI schreibt den Code. Der Prototyp funktioniert. Der Gründer ist begeistert. Sechs Monate später brennt das System, die Datenbank schmilzt und ein richtiger Ingenieur wird hinzugezogen, um die schlechte Nachricht zu überbringen: Das Ganze muss von Grund auf neu gebaut werden.

Ich nenne das Vibe Coding. Software bauen basierend auf Vibes statt architektonischem Verständnis. Die KI kann syntaktisch korrekten Code schreiben, aber sie kann nicht die strategischen Entscheidungen treffen, die bestimmen ob ein System skaliert, performt oder überhaupt den Kontakt mit echten Nutzern überlebt.

Das fundamentale Problem: KI schreibt Code, nicht Architektur

Lass mich etwas klarstellen: KI-Coding-Assistenten sind wirklich nützlich. Ich benutze sie täglich. Sie beschleunigen Entwicklung, reduzieren Boilerplate und helfen beim Erkunden unbekannter APIs.

Aber es gibt einen Unterschied zwischen Code schreiben und Systeme designen.

Code schreiben ist Logik in Syntax übersetzen. Darin ist KI exzellent.

Systeme designen erfordert:

  • Verstehen wie Daten fließen und über Zeit wachsen
  • Engpässe antizipieren bevor sie auftreten
  • Tradeoffs zwischen konkurrierenden Anforderungen machen
  • Wissen was du nicht weißt

KI kann das nicht. Sie kennt dein Business nicht. Sie kennt deine Skalierung nicht. Sie weiß nicht, dass deine "einfache User-Tabelle" in 18 Monaten 10 Millionen Zeilen haben wird. Sie optimiert für die unmittelbare Anfrage, nicht für die langfristige Architektur.

Das Ergebnis ist Code der heute funktioniert und morgen katastrophal scheitert.

Datenbankarchitektur: Wo Vibe Coding zuerst stirbt

Die Datenbank ist wo architektonische Schulden am schnellsten akkumulieren. Eine schlechte Schema-Entscheidung in Woche eins wird zum Migrations-Albtraum mit Millionen Zeilen in Jahr zwei.

Das N+1 Query Problem

Das ist der häufigste Performance-Killer in vibe-gecodeten Anwendungen. Es passiert wenn du eine Liste von Items holst und dann für jedes Item eine separate Datenbankabfrage machst.

# Die vibe-gecodete Version (N+1 Queries)
orders = Order.objects.all()  # 1 Query
for order in orders:
    print(order.customer.name)  # N Queries (eine pro Order)

# 1000 Orders = 1001 Datenbankabfragen
# Die korrekte Version (2 Queries)
orders = Order.objects.select_related('customer').all()
for order in orders:
    print(order.customer.name)  # Keine zusätzlichen Queries

# 1000 Orders = 2 Datenbankabfragen

Die vibe-gecodete Version funktioniert perfekt mit 10 Orders in der Entwicklung. Sie bringt die Datenbank mit 10.000 Orders in Produktion in die Knie.

Fehlende Indizes

Jede WHERE-Klausel, jedes ORDER BY, jede JOIN-Bedingung braucht einen Index. Ohne Indizes scannt die Datenbank jede Zeile in der Tabelle.

-- Query die 1000x pro Sekunde läuft
SELECT * FROM orders WHERE user_id = 123 AND status = 'pending';

Ohne Index auf (user_id, status) scannt diese Query die gesamte Orders-Tabelle. Bei 100.000 Zeilen ist sie langsam. Bei 10 Millionen Zeilen ist sie ein Produktions-Incident.

KI fügt selten Indizes hinzu, weil Migrationen die "nur eine Tabelle hinzufügen" einfacher sind. Der Performance-Impact ist unsichtbar bis zur Skalierung.

Falsche Datenbankwahl

Vibe Coding gravitiert zu SQLite (ist der Default) oder PostgreSQL (die KI kennt es). Aber die Wahl sollte von Zugriffsmustern abhängen:

ZugriffsmusterRichtige WahlFalsche Wahl
Relationale Daten mit komplexen JoinsPostgreSQL, MySQLMongoDB
Dokument-Speicherung, Schema-FlexibilitätMongoDBPostgreSQL mit JSONB überall
Hoher Schreib-Durchsatz, ZeitreihenTimescaleDB, ClickHousePostgreSQL
Session-Storage, CachingRedisPostgreSQL
VolltextsucheElasticsearch, MeilisearchLIKE '%term%' auf PostgreSQL

Die richtige Sprachwahl

Python: Der Vibe-Coder-Default

Stärken: Riesiges Ökosystem besonders für Data Science und ML, niedrige Einstiegshürde, exzellente KI/ML-Bibliotheken.

Schwächen: Langsam. Der Global Interpreter Lock (GIL) limitiert echte Parallelität. Dynamische Typisierung erzeugt Laufzeitfehler, die statische Sprachen zur Compile-Zeit fangen. Dependency-Management ist ein Albtraum.

Wann Python nutzen: Data Pipelines und ML Workloads, Prototyping und MVPs, Glue Code zwischen Systemen.

Wann NICHT Python nutzen: High-Throughput APIs (erwäge Go, Rust oder Elixir), CPU-gebundene Workloads, große Teams wo Typsicherheit Bugs verhindert.

Ruby: Der Produktivitäts-Champion

Stärken: Rails ist unglaublich produktiv für CRUD-Anwendungen, Convention over Configuration reduziert Entscheidungen, ausgereiftes Ökosystem mit gelösten Problemen.

Wann Ruby nutzen: Web-Anwendungen mit komplexer Business-Logik, Startups die schnell vorankommen müssen, E-Commerce (Solidus, Spree).

Go: Die pragmatische Wahl für Skalierung

Stärken: Kompiliert, schnell, effizient. Eingebaute Concurrency (Goroutines). Einfache Sprache (leicht anderen Code zu lesen). Exzellent für Microservices und APIs.

Elixir: Das Skalierungs-Geheimtipp

Stärken: Auf Erlang VM gebaut (kampferprobt für Telekom-Skalierung), echte Concurrency mit Lightweight Processes, Phoenix Framework ist Rails-ähnliche Produktivität mit besserer Performance, LiveView eliminiert Frontend-JS für viele Use Cases.

Framework-Analyse: Das Gute, das Schlechte und das Hässliche

Streamlit: Der Prototyp der nicht in Produktion hätte gehen sollen

Was es ist: Eine Python-Bibliothek für Data Apps mit minimalem Code.

Die Anziehungskraft: Du kannst ein funktionierendes Dashboard in 50 Zeilen Code bauen.

Wo es bricht:

  1. Kein persistenter State. Jede Interaktion führt das gesamte Script neu aus. Das ist okay für eine Demo. Es ist katastrophal für eine Produktions-App.

  2. Kein URL-Routing. Du kannst nicht zu einer bestimmten Seite oder einem State linken.

  3. Keine eingebaute Authentifizierung. Du brauchst Drittanbieter-Libraries.

  4. Kann gleichzeitige Nutzer nicht gut handhaben. Jeder Nutzer führt seinen eigenen Python-Prozess aus. 100 gleichzeitige Nutzer = 100 Python-Prozesse = Server brennt.

Die Obergrenze: 10 gleichzeitige Nutzer bei leichter Datenexploration. Darüber hinaus brauchst du eine echte Anwendung.

Echtes Beispiel: Ein Kunde baute seine gesamte Analytics-Plattform in Streamlit. 50 Dashboards, 200 Nutzer. Der Server brauchte 64GB RAM nur um zu laufen. Queries liefen bei jeder Interaktion neu. Der Rebuild in eine echte FastAPI + React Anwendung dauerte 6 Monate.

Gradio: Noch limitierter als Streamlit

Was es ist: Eine Library für ML-Model-Demos. Bild hochladen, Prediction bekommen.

Wo es bricht: Alles was bei Streamlit bricht, plus: Designt für Demos, nicht für Anwendungen. Keine User, Sessions oder persistenten Daten. Limitierte UI-Komponenten.

Die Obergrenze: Eine Model-Demo mit wenigen gleichzeitigen Nutzern. Alles darüber hinaus ist Missbrauch.

Plotly Dash: Streamlits ältere Schwester

Was es ist: Ein Framework für analytische Web-Anwendungen in Python.

Wo es bricht:

  1. Callback Hell. Komplexe Anwendungen werden zu einem Netz aus Callbacks, das unmöglich nachzuverfolgen ist.

  2. Performance degradiert mit Komplexität. Jede Interaktion triggert Callback-Ketten.

  3. Limitiert auf Dashboards. Keine Authentifizierung, kein User-Management, keine Zahlungsabwicklung.

Die Obergrenze: Interne Dashboards mit <50 gleichzeitigen Nutzern.

Flask: Das Microframework das ein Macro brauchte

Was es ist: Ein minimales Python Web Framework. Du bekommst Routing und nicht viel mehr.

Wo es bricht:

  1. Alles ist dein Problem. Kein ORM (füge SQLAlchemy hinzu), keine Migrations (füge Alembic hinzu), keine Auth (füge Flask-Login hinzu). Jede Ergänzung ist eine Dependency mit eigener Lernkurve.

  2. Keine Convention. Jedes Flask-Projekt ist anders strukturiert.

  3. Sync per Default. Flask ist synchron. Wenn du Async brauchst, brauchst du Workarounds.

Die Obergrenze: Flask KANN zu großen Anwendungen skalieren, aber es erfordert Disziplin die Vibe Coding nicht bietet.

Django: Das Batteries-Included Monolith

Was es ist: Ein vollständiges Python Web Framework. ORM, Migrations, Auth, Admin, Forms, alles eingebaut.

Wo es bricht:

  1. Das ORM ist eine leaky Abstraction. Djangos ORM ist convenient bis du Performance brauchst. Dann entdeckst du select_related, prefetch_related, defer, only und merkst dass du gegen das ORM kämpfst statt es zu nutzen.

  2. Synchron per Default. Django 4.0+ hat Async-Support, aber das ORM ist noch sync.

  3. Monolithische Architektur kämpft gegen Microservices. Django will eine große Anwendung sein.

Die Obergrenze: Django kann zu sehr großen Anwendungen skalieren (Instagram läuft auf Django). Aber es erfordert Verständnis der ORM-Fallstricke und Caching-Strategien.

FastAPI: Das API-Framework das gebeten wird alles zu tun

Was es ist: Ein modernes Python Framework für APIs. Type Hints, automatische OpenAPI-Docs, Async-Support.

Wo es bricht:

  1. Es ist ein API-Framework, kein Application-Framework. Kein ORM, keine Migrations, kein Admin, keine Auth, kein Frontend.

  2. Async ist nicht gratis. FastAPI ist async per Default, was super ist bis du synchronen Code aufrufst (die meisten Python-Libraries). Dann brauchst du run_in_executor oder du blockierst den Event Loop.

Die Obergrenze: FastAPI ist exzellent für APIs. Es ist kein Full-Stack Framework.

Reflex: Das neue Kind mit Versprechen

Was es ist: Ein Python Framework für Full-Stack Web Apps. Schreibe Python, bekomme ein React Frontend.

Wo es bricht:

  1. Unreifes Ökosystem. Reflex ist neu. Die Component Library ist limitiert. Edge Cases sind undokumentiert.

  2. Kompilierungsschritt. Reflex kompiliert Python zu React. Wenn die Kompilierung bricht, erfordert Debugging Verständnis von BEIDEN Python UND React Internals.

  3. Performance Overhead. Jede State-Änderung macht einen Roundtrip zum Python-Backend.

Die Obergrenze: Interne Tools und MVPs wo Entwicklungsgeschwindigkeit wichtiger ist als Performance.

Rapid Development Frameworks die tatsächlich skalieren

Ruby on Rails: Das Original

Warum es funktioniert:

  1. 15+ Jahre Produktions-Lessons. Rails wurde auf Millionen von Nutzern skaliert (Shopify, GitHub, Airbnb). Die Fallstricke sind bekannt. Die Lösungen existieren.

  2. Convention bedeutet Konsistenz. Jede Rails-App ist gleich strukturiert.

  3. ActiveRecord ist ausgereift. Das ORM hat jedes Optimierungs-Tool das du brauchst.

  4. Full Stack per Default. Auth (Devise), Admin (ActiveAdmin), Background Jobs (Sidekiq), Email (ActionMailer) integrieren nahtlos.

Phoenix (Elixir): Rails mit Erlangs Power

Warum es funktioniert:

  1. Echte Concurrency. Erlang-Prozesse sind leichtgewichtig (führe Millionen davon aus). Kein GIL.

  2. Realtime per Default. Phoenix Channels handhaben WebSockets elegant. LiveView eliminiert Frontend-JavaScript für die meisten Use Cases.

  3. Fehlertoleranz. Die Erlang "let it crash" Philosophie bedeutet Fehler sind isoliert.

  4. Performance. Phoenix handhabt mehr gleichzeitige Verbindungen pro Server als Rails oder Django.

Warum PHP der schlimmste Übeltäter ist

Ich habe das für den Schluss aufgehoben weil PHP besondere Aufmerksamkeit verdient. Es ist die häufigste Sprache für vibe-gecodete Projekte weil KI so viel PHP gesehen hat und weil es sofort "funktioniert".

Aber PHP hat fundamentale Design-Probleme die sich über Zeit aufaddieren.

Die Sprachdesign-Probleme

Inkonsistente Standardbibliothek:

// Ist needle oder haystack zuerst? Es kommt darauf an!
strpos($haystack, $needle);     // haystack, needle
array_search($needle, $haystack); // needle, haystack
in_array($needle, $haystack);   // needle, haystack
strstr($haystack, $needle);     // haystack, needle

Jede Funktion ist ein Gedächtnistest. Die KI schreibt es die Hälfte der Zeit falsch. Du schreibst es die Hälfte der Zeit falsch.

Schwache Typisierung erzeugt stille Fehler:

// All das ist "gleich" in PHP
0 == "0"        // true
0 == ""         // true
"0" == ""       // false (warte, was?)
null == false   // true
0 == null       // true

// Das führt zu echten Sicherheitslücken
if ($password == $user_input) {  // FALSCH: nutze === 
    // Angreifer kann mit Type Juggling umgehen
}

Stille Fehlerbehandlung:

// Das gibt still null zurück statt zu scheitern
$result = @some_function_that_errors();

Globaler State überall:

// $_GET, $_POST, $_SESSION, $_COOKIE sind alle global
// Das macht Testen fast unmöglich
function get_user() {
    return User::find($_SESSION['user_id']);  // Global!
}

Die Ökosystem-Probleme

Composer kam spät. Python hatte pip, Ruby hatte gems, Node hatte npm. PHP bekam Composer 2012, Jahrzehnte nach dem Sprach-Launch. Millionen PHP-Anwendungen wurden mit manuellen include Statements gebaut.

Kein Concurrency-Modell. PHP ist Request-Response. Jeder Request ist ein neuer Prozess. Kein eingebautes Async, keine WebSockets ohne Extensions.

Framework-Fragmentierung. Laravel, Symfony, CodeIgniter, Yii, CakePHP, Zend/Laminas. Jedes hat verschiedene Conventions, verschiedene ORMs, verschiedene Patterns.

Wann PHP akzeptabel ist

Nutze PHP wenn:

  • Du WordPress, Drupal oder Magento erweiterst (du hast keine Wahl)
  • Dein Team PHP bereits gut kennt
  • Du Laravel mit modernen PHP-Practices nutzt
  • Deployment-Constraints PHP erfordern (Shared Hosting)

Nutze PHP NICHT wenn:

  • Du ein neues Projekt mit freier Sprachwahl startest
  • Du Realtime-Features baust
  • Performance wichtig ist
  • Du Senior Engineers anziehen willst (PHP-Stigma ist real beim Hiring)

Die Vibe Coding Checkliste: Zeichen dass du auf Probleme zusteuerst

Datenbank-Warnsignale

  • Keine Foreign Keys definiert
  • Keine Indizes außer Primary Keys
  • Alle Spalten sind VARCHAR(255) oder TEXT
  • Keine Migrations (Schema-Änderungen sind manuelles SQL)
  • ORM für alles genutzt, niemals Raw SQL
  • SQLite in Produktion

Architektur-Warnsignale

  • Alle Logik in Route Handlern (kein Service Layer)
  • Keine Background Job Verarbeitung (alles synchron)
  • Secrets im Code (nicht in Environment Variables)
  • Keine Caching-Schicht
  • Monolithische Funktions-Dateien (1000+ Zeilen Dateien)

Framework-Warnsignale

  • Streamlit/Gradio für Produktions-Anwendungen
  • Flask ohne SQLAlchemy/Alembic
  • FastAPI das versucht ein Full-Stack Framework zu sein

Fazit: Architektur ist nicht automatisierbar

KI-Coding-Assistenten sind mächtige Werkzeuge. Sie beschleunigen Entwicklung, reduzieren Boilerplate und helfen beim Erkunden von unbekanntem Terrain.

Aber sie können architektonisches Verständnis nicht ersetzen. Sie können keine klärenden Fragen über Skalierung stellen. Sie können keine Engpässe antizipieren. Sie können nicht die Tradeoffs machen die über Erfolg oder Scheitern entscheiden.

Der teuerste Code ist Code der neu geschrieben werden muss. Die günstigste Architekturentscheidung ist die, die vor der ersten Zeile Code getroffen wird.

Wenn du etwas baust das halten soll:

  1. Investiere Zeit in Architektur vor dem Coding. Whiteboard das Datenmodell. Identifiziere Zugriffsmuster. Plane für 10x deine erwartete Skalierung.

  2. Wähle langweilige Technologie. Rails, Django, Phoenix, Laravel haben bekannte Skalierungspfade. Neuartige Frameworks haben unbekannte Fehlermodi.

  3. Stelle Erfahrung früh ein. Ein Senior Engineer der Architekturentscheidungen trifft spart 10 Junior Engineers die sie später fixen.

  4. Teste unermüdlich. Tests sind der einzige Weg sicher zu refactoren.

  5. Nutze KI für Implementierung, nicht für Design. Lass KI den Code schreiben der deine Architektur implementiert. Lass KI nicht die Architektur designen.

Der vibe-gecodete Prototyp der heute funktioniert wird zum Legacy-System das morgen Fortschritt blockiert. Bau für morgen.

Ich habe vibe-gecodete Projekte in E-Commerce, Fintech und SaaS neu gebaut. Die Muster sind konsistent: falsche Framework-Wahl, fehlende Datenbank-Indizes, keine Trennung der Concerns und der Glaube dass "es funktioniert" bedeutet "es skaliert". Wenn du eine Codebase erbst und eine ehrliche Einschätzung brauchst was zu retten ist, oder wenn du neu startest und die Architektur von Tag eins richtig machen willst, kann ich helfen. Lass uns reden bevor die technischen Schulden sich aufaddieren.

Baust du etwas Neues und willst Architekturfehler vermeiden? Oder erbst du eine Codebase die eine ehrliche Einschätzung braucht? Ich kann dir helfen Framework-Entscheidungen zu evaluieren, skalierbare Architekturen zu designen und einen Weg nach vorne zu schaffen. Meld dich bevor die technischen Schulden sich aufaddieren.