CommunityCodierung & Entwicklunggithub.com

Baukaalm/system-design-first

System-Design-Review vor dem Bauen einer Funktion mit eigenem Datenfluss: Anforderungen, Lastabschätzungen, Ist- vs. Soll-Zustand, Pattern-Abwägungen und ein kurzes Design-Briefing mit dem "Warum". Verwenden, wenn eine Aufgabe einen Service, einen Endpunkt mit Speicher, eine Integration, einen Echtzeitkanal, eine Ereignispipeline, einen geplanten Job oder eine Datenmodelländerung hinzufügt; wenn der Benutzer fragt, wie man etwas entwirft oder skaliert, um eine Architektur zu erklären oder zu diagrammen; oder wenn Last, Latenz, Konsistenz, Fan-Out, Warteschlangen oder Caching den Ansatz bestimmen. Textkopien, Umbenennungen, Styling und lokale Fehlerbehebungen gehen direkt in den Code.

Was ist system-design-first?

Dieser Skill führt ein strukturiertes System-Design-Review durch, bevor eine Codeänderung vorgenommen wird. Er stellt typische, aber oft übersehene Fragen zu Last, Skalierung, Datenkonsistenz und Abhängigkeiten explizit und erzwingt eine fundierte Entscheidungsfindung auf Basis von Schätzungen und Pattern-Abwägungen. Der Skill unterstützt verschiedene Tiefenstufen – von trivialen Änderungen (L0) über lokale Anpassungen (L1) bis hin zu Features (L2) und Subsystemen (L3). Für L2/L3 wird ein detailliertes Design-Briefing erstellt, das den Umfang definiert, Last und Speicher abschätzt, den Ist-Zustand der Codebasis analysiert, einen Soll-Zustand mit API-Vertrag und Datenmodell vorschlägt, Risiken und Tiefenanalysen durchführt und eine Implementierungsreihenfolge angibt. Der Skill interagiert mit dem Benutzer und passt die Tiefe der Analyse an die Komplexität der Aufgabe an. Er ist für Plattformen wie Claude Code oder Cursor geeignet und kann auch für frontend-lastige Aufgaben verwendet werden.

Funktioniert mit~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/Baukaalm/system-design-first/tree/HEAD

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

System-Design zuerst

Die meisten Tickets beschreiben was gebaut werden soll und verstecken die Fragen, die entscheiden, ob es den Kontakt mit der Produktion überlebt: wie viele Benutzer, wie oft, wie viele Daten, was passiert, wenn eine Abhängigkeit langsam ist, wem gehört die Wahrheit, wenn zwei Schreiber konkurrieren. Dieser Skill macht diese Fragen explizit bevor Code geschrieben wird, in einer Form, die der Autor der Aufgabe lesen und widersprechen kann.

Der Durchlauf ist: Umfang → Schätzung → High-Level-Design → Deep Dive → Zusammenfassung, angewandt auf echte Arbeit: Es gibt eine bestehende Codebasis, einen Autor mit einer Absicht und ein Budget. Das Ziel ist ein klares Bild der Funktion aus Sicht des Systems.

Antworte in der Sprache, in der der Benutzer schreibt. Das Briefing ist für ihn, nicht für dich.

1. Zuerst die Tiefe abschätzen

Ein Tippfehler zu überdimensionieren ist genauso falsch wie einen Zahlungsfluss zu unterdimensionieren. Wähle die Stufe, sag es in einem Satz und gib entsprechend aus.

StufeTypische AufgabeWas du produzierst
L0 – trivialTextänderung, Umbenennung, Style-Anpassung, offensichtlicher Fehler mit lokaler KorrekturNichts extra. Höchstens einen Satz, wenn ein verstecktes Risiko besteht ("Dieses Label wird auch 24h im CDN gecached"). Dann einfach die Aufgabe erledigen.
L1 – lokale ÄnderungNeues Feld, neuer Filter, kleine Endpunktänderung, ein Hook, eine Query-AnpassungEine 3-7-zeilige Design-Prüfung inline: was es berührt, auf welcher Last es reitet, die eine Sache, die beißen könnte (N+1, Cache-Invalidierung, Paginierung, Idempotenz). Dann implementieren.
L2 – FeatureNeuer Bildschirm mit Datenfluss, neuer Endpunkt + Speicher, Benachrichtigungen, Suche, Export, Integration mit einem DrittanbieterDas Design-Briefing (Abschnitt 4), etwa eine Seite. Dann nach dem Briefing implementieren.
L3 – SubsystemNeuer Service, Echtzeitkanal, Ereignispipeline, Multi-Tenant-Datenmodell, Migration eines Hot Paths, alles mit "Skalierung" im TicketVollständiges Briefing plus einen Deep Dive pro riskanter Komponente, betrachtete Alternativen, Migrationspfad, was nach dem Start gemessen werden soll.

Signale, die eine Aufgabe eine Stufe nach oben verschieben: benutzerseitige Latenz, gleichzeitige Schreiber, Fan-Out (ein Ereignis → viele Empfänger), unbegrenztes Wachstum einer Tabelle oder Liste, Drittanbieter-Ratenlimits, Geld, PII, alles, was nach einem Zeitplan läuft, oder "vorübergehende" Lösungen, die offensichtlich bleiben werden. Signale, die sie nach unten verschieben: interne Tools mit einer Handvoll Benutzern, Daten, die für immer in den Speicher passen, Feature-Flag-Experimente mit einem Kill-Switch.

Wenn der Benutzer explizit nach einem Design-Review oder einer tieferen Analyse fragt, behandle es als L3, unabhängig von der Größe.

2. Der Durchlauf, Schritt für Schritt

Arbeite diese in der Reihenfolge durch. Für L1 komprimiere sie in ein paar Zeilen; für L2/L3 wird jeder Schritt zu einem Abschnitt des Briefings. references/framework.md enthält die Fragenchecklisten für jeden Schritt; lies es beim ersten L2+-Durchlauf in einer Sitzung.

Schritt 1 — Verstehen und abgrenzen

  • Formuliere das Feature in einem Absatz aus Sicht des Systems neu: Akteure, Auslöser, Eingaben, Ausgaben, Nebeneffekte.
  • Trenne funktionale Anforderungen (was es tut) von nicht-funktionalen (wie gut: Skalierung, Latenz, Verfügbarkeit, Konsistenz, Haltbarkeit, Sicherheit, Kosten, Betriebsfähigkeit). Tickets nennen fast nie die zweite Art; leite sie aus dem Produktkontext ab und sage, dass sie abgeleitet sind.
  • Schreibe auf, was außerhalb des Rahmens liegt, damit das Briefing nicht still wächst.
  • Sammle die Absicht des Autors: Tickettext, PR-Beschreibung, Kommentare, verlinkte Designs, bestehende ADRs, wie ähnliche Funktionen in diesem Repo gebaut wurden. Der Autor hat normalerweise ein Design im Kopf; bringe es an die Oberfläche, anstatt es zu ersetzen.
  • Stelle dem Benutzer nur Fragen, die das Design materiell verändern (z. B. "Muss das innerhalb einer Sekunde sichtbar sein, oder ist eine Minute in Ordnung?"). Für alles andere nimm eine Annahme an und mach weiter; Annahmen kommen ins Briefing.

Schritt 2 — Schätzen

Zahlen verwandeln Meinungen in Entscheidungen. Mache eine Überschlagsrechnung, auch wenn das Ticket keine hat; references/estimation.md enthält die Referenzzahlen (Latenzleiter, Zweierpotenzen, Verfügbarkeitsneunen, Kapazitäten pro Knoten) und durchgerechnete Beispiele.

  • Benutzer / Mandanten → täglich aktive → Aktionen pro Tag → durchschnittlicher und Spitzen-QPS (Spitze ist normalerweise 2-5× der Durchschnitt, mehr für Burst-Flows wie "jeder öffnet die App um 9:00").
  • Lese-/Schreibverhältnis, Payload-Größe → Speicher pro Tag / Jahr, Bandbreite.
  • Wachstum: Wie hoch ist die Zahl in 12 Monaten, wenn das Produkt erfolgreich ist?
  • Wo reale Zahlen existieren (Analysen, DB-Zeilenanzahlen, bestehende Dashboards, Konfigurationslimits), verwende sie und zitiere die Quelle; andernfalls gib einen Bereich an und markiere ihn als Annahme.

Verwende dann die Zahlen, um Pattern auszuschließen, nicht nur um sie zu rechtfertigen: "Bei 30 Schreibvorgängen/s ist eine Postgres-Tabelle mit Index in Ordnung; eine Warteschlange wird nicht für den Durchsatz benötigt, sondern nur, wenn wir Wiederholungen und Entkopplung vom E-Mail-Anbieter wollen."

Schritt 3 — Das aktuelle Design abbilden (Ist-Zustand)

Lies den Code, bevor du ihn beschreibst. Nenne reale Dateien, Module, Tabellen, Endpunkte, Jobs, Caches, Warteschlangen. Erfinde keine Komponenten.

  • Welche Komponenten berührt das Feature? Zeichne den Datenfluss in einem kurzen Textdiagramm (Client → BFF → Service → Postgres, Ereignis → Warteschlange → Worker).
  • Wo ist der Zustand und wem gehört er (DB, Cache, Client-Store, URL)?
  • Welche vorhandenen Primitive können wiederverwendet werden (eine Outbox-Tabelle, ein Job-Runner, ein Query-Cache, ein WebSocket-Hub, eine gemeinsame Pagination-Komponente)?
  • Hot Paths, bekannte Engpässe, bestehende SPOFs, aktuelle Limits (Ratenlimits, Seitengrößen, Timeouts), die das Feature erbt.
  • Für eine Frontend-Aufgabe ist der Ist-Zustand immer noch ein System: Datenabrufschicht, Cache- Richtlinie, Bundle-Grenzen, Echtzeittransport — siehe references/frontend.md.

Schritt 4 — Das Zieldesign vorschlagen (Soll-Zustand)

Beginne mit der Absicht des Autors. Wenn sie solide ist, sag es und schärfe sie; wenn sie im Konflikt mit den Zahlen oder einem bekannten Fehlermodus steht, zeige den Konflikt mit seiner Konsequenz und biete die kleinste Änderung an, die ihn behebt. Der Autor entscheidet; deine Aufgabe ist es, den Kompromiss sichtbar zu machen.

  • High-Level-Design als Textdiagramm, plus den API-Vertrag (Endpunkte / Ereignisse / Nachrichten mit Formen) und das Datenmodell (Tabellen, Schlüssel, Indizes, Aufbewahrung).
  • Nenne für jede nicht-triviale Wahl das Pattern und die Alternative, die du verworfen hast, mit dem Grund, der mit den Zahlen aus Schritt 2 zusammenhängt. references/patterns.md ist der Katalog: Skalierung, Caching, Async/Warteschlangen, Datenspeicher und Konsistenz, API-Stile und Echtzeittransport, Ratenbegrenzung, ID-Generierung, Zuverlässigkeit, Beobachtbarkeit — jeweils mit "verwenden, wenn / vermeiden, wenn / Kompromisse".
  • Ordne das Feature einem kanonischen System zu, wenn eines passt ("Dies ist ein Benachrichtigungssystem: Warteschlange + kanalspezifische Worker + Deduplizierung", "Dies ist Newsfeed- Fan-Out", "Dies ist ein Ratenbegrenzer"). Der letzte Abschnitt des Katalogs listet die kanonischen Formen und ihre Standardbausteine auf. Die Analogie gibt dem Leser einen bekannten Referenzpunkt und eine Checkliste dessen, was solche Systeme normalerweise benötigen.
  • Bevorzuge die vorhandenen Primitive des Repos und das einfachste Design, das die Zahlen mit ausreichender Reserve erfüllt. Sage explizit, welche Upgrades aufgeschoben werden und welches Signal sie auslösen würde ("Füge ein Read-Replica hinzu, wenn das p95 dieser Query 200 ms überschreitet oder die Tabelle 50 Mio. Zeilen überschreitet").

Schritt 5 — Deep Dive in das, was kaputtgehen kann

Wähle für L2 die ein oder zwei riskantesten Teile; für L3 gehe alle durch. Standardfragen in grober Reihenfolge, wie oft sie beißen:

  1. Parallelität & Idempotenz — Doppelte Übermittlung, Wiederholungen, zwei Schreiber, At-Least-Once-Zustellung. Wo ist der Idempotenzschlüssel? Was ist die eindeutige Einschränkung?
  2. Konsistenz — Wer liest veraltete Daten und wie lange; ist das akzeptabel; Cache-Invalidierungspfad; Read-Your-Own-Writes.
  3. Fehler einer Abhängigkeit — Anbieter ausgefallen, Warteschlange hinkt hinterher, Remote-Modul kann nicht geladen werden. Timeouts, Wiederholungen mit Jitter, Circuit Breaker, Graceful Degradation, was der Benutzer sieht.
  4. Hot Spots — Hot Keys, Star-Mandanten, unbegrenzte Listen, N+1, Full-Table-Scans, fehlender Index, Thundering Herd bei Cache-Ablauf.
  5. Wachstum — Die Tabelle/Liste/Warteschlange, die unbegrenzt wächst; Aufbewahrung, Archivierung, Paginierung (Cursor statt Offset), Partitionierung.
  6. Migration & Rollout — Backfill, Dual-Write-Zeitraum, Feature-Flag, Rollback-Pfad, rückwärtskompatible Vertragsänderungen.
  7. Sicherheit & Datenschutz — Autorisierung auf Datenebene (Mandantenisolierung), PII in Logs/Warteschlangen, Ratenbegrenzung auf öffentlichen Endpunkten, Eingabevalidierung.
  8. Beobachtbarkeit — Welche Metrik beweist, dass es funktioniert (SLI), welcher Alarm schlägt an, wenn es das nicht tut, was zu loggen ist, um eine einzelne Anfrage zu debuggen.

Schritt 6 — Zusammenfassen, Visualisierung anbieten

Diagramme kosten Tokens, also sind sie opt-in. Das Briefing selbst verwendet nur einzeilige Textflüsse (Client → API → Postgres).

Beende für L2 und L3 das Briefing mit einer Frage zusammen mit den offenen Fragen in der Sprache des Benutzers:

Architektur zeichnen? 1 — Ist-/Soll-Diagramm im Terminal · 2 — plus Design-Ordner (Mermaid + architecture.html) · 3 — nein

  • Zeichne nur, nachdem der Benutzer 1 oder 2 gewählt hat, gemäß references/visualization.md. Warte nicht auf die Antwort, um mit der Implementierung zu beginnen; wenn der Benutzer weitermacht, ohne zu antworten, ist es ein "Nein".
  • Überspringe die Frage und zeichne nur dann sofort, wenn der Benutzer bereits nach einem Diagramm, einem Bild, einer Visualisierung oder dem Design-Ordner gefragt hat.
  • Wenn niemand antworten kann (ein nicht-interaktiver Durchlauf, CI, ein Eval), zeichne nicht und frage nicht; erwähne in einer Zeile, dass Diagramme auf Anfrage verfügbar sind.
  • Biete es niemals für L0 oder L1 an.

Erstelle das Briefing (nächster Abschnitt), dann fahre mit der Aufgabe fort: implementiere gemäß dem Briefing, behalte das Briefing auch in der PR-/MR-Beschreibung und liste offene Fragen für den Autor auf, anstatt sie stillschweigend zu entscheiden.

3. Urteilsregeln

  • Zahlen vor Patterns. Empfehle niemals Kafka, Sharding, CQRS, einen dedizierten Cache-Cluster oder Microservices ohne eine Schätzung, die sie benötigt. Einfachheit ist ein Feature; Komplexität muss sich ihren Platz verdienen.
  • Erklären, nicht belehren. Jede Empfehlung bringt ein einziges "weil" mit sich, das der Autor überprüfen kann. Analogien zu kanonischen Systemen sind willkommen; Buzzword-Listen sind es nicht.
  • Respektiere das Design des Autors. Präsentiere Meinungsverschiedenheiten als "X wird Y bei Z-Last verursachen; die billigste Lösung ist W". Wenn der Autor immer noch seinen Weg bevorzugt, implementiere seinen Weg und notiere das Risiko im Briefing.
  • Bestehender Code ist Beweis. Lese ihn. Ein Briefing, das Komponenten beschreibt, die nicht existieren, ist schlimmer als kein Briefing.
  • Trenne Muss von Kann. Markiere jede Empfehlung als "jetzt benötigt", "vor dem Start benötigt" oder "bei ~N Benutzern benötigt".
  • Frontend zählt. Client-Caching, Paginierung, optimistische Updates, Echtzeittransport, Bundle-Grenzen und Fehlerisolierung sind Systemdesign; references/frontend.md deckt die clientseitige Version jedes Schritts ab.
  • Bleibe in der Sprache und dem Wortschatz des Benutzers. Übersetze Pattern-Namen, wenn das Team es tut; behalte den englischen Begriff beim ersten Mal in Klammern.

4. Das Design-Briefing

Verwende diese Struktur für L2 und L3. Behalte die Überschriften; lasse einen Abschnitt nur dann weg, wenn er wirklich leer ist, und sage es in einem Satz. Ziel ist eine Seite für L2. references/brief-template.md enthält ein ausgefülltes Beispiel und die kompakte L1-Form.

# Design-Briefing: <Feature>

**Tiefe:** L2 · **Status:** Vorschlag · **Absicht des Autors:** <eine Zeile>

## 1. Umfang
Funktional: ...
Nicht-funktional (sofern nicht anders angegeben, abgeleitet): Skalierung · Latenz · Verfügbarkeit · Konsistenz · Sicherheit · Kosten
Außerhalb des Rahmens: ...
Annahmen: ...

## 2. Schätzungen
| Metrik | Jetzt | +12 Monate | Quelle |
| --- | --- | --- | --- |
| DAU / Mandanten | | | |
| Spitzen-QPS (Lesen / Schreiben) | | | |
| Speicherwachstum | | | |
Fazit: <was die Zahlen erlauben / verbieten>

## 3. Aktuelles Design (Ist-Zustand)
<einzeiliger Textfluss> · Zustandsbesitz · wiederverwendbare Primitive · geerbte Limits
Dateien: ...

## 4. Zieldesign (Soll-Zustand)
<einzeiliger Textfluss> · API-Vertrag · Datenmodell · kanonische System-Analogie
Pattern-Wahl: <Pattern> — weil <Grund>; <Alternative> verworfen, weil <Grund>.

## 5. Risiken und Deep Dives
1. <Risiko> → Absicherung (jetzt benötigt / vor dem Start / bei N)
...

## 6. Rollout, Migration, Beobachtbarkeit
Flags, Backfill, Rollback · SLI + Alarm · was zu loggen ist

## 7. Offene Fragen an den Autor
- ...
- Architektur zeichnen? 1 — Terminal-Diagramm · 2 — plus Design-Ordner · 3 — nein

## 8. Implementierungsplan
Schritte in Reihenfolge, jeder klein genug zum Reviewen.

5. Referenzen — was wann zu lesen ist

DateiLesen, wenn
references/framework.mdErster L2+-Durchlauf in einer Sitzung: Fragenchecklisten pro Schritt, NFR-Liste, wie man die Absicht des Autors extrahiert, Analyse-Anti-Pattern.
references/estimation.mdImmer, wenn du eine Zahl brauchst: Latenzleiter, Neunen, Kapazitäten pro Knoten, QPS-/Speicher-Mathematik, durchgerechnete Beispiele.
references/patterns.mdAuswählen oder Rechtfertigen eines Patterns; Zuordnen eines Features zu einem kanonischen System (Chat, Feed, Benachrichtigungen, Such-Autovervollständigung, Dateisynchronisation, Ratenbegrenzer, KV-Speicher, ID-Generator, Zahlungen, ...). Hat ein Inhaltsverzeichnis.
references/frontend.mdDie Aufgabe ist eine UI-/SPA-/Micro-Frontend-Änderung: Datenabruf-Cache, Paginierung, Echtzeit, Bundle-Grenzen, Fehlerisolierung, clientseitige Zahlen.
references/brief-template.mdSchreiben des Briefings: vollständiges L2-Beispiel und die kompakte L1-Inline-Form.
references/visualization.mdNur nachdem der Benutzer nach Diagrammen gefragt hat (Schritt 6). Zeichnen: Terminal-Box-Diagramm-Regeln, Mermaid-Konventionen, Design-Ordner-Layout, wie man assets/architecture.html füllt.

Verwandte Skills