VPSSpark Blog
← Zurück zum Dev-Tagebuch

Wo iOS CI/CD zuerst bricht, wenn das Team 20 Entwickler erreicht

Server-Notizen · 2026.06.04 · ~16 Min. Lesezeit

Team analysiert iOS-CI-Build-Warteschlange und Skalierungsausfall
CI-Review: queue time vs. Kompilierdauer

Dieser Artikel beschreibt ein iOS CI/CD Scaling Failure Model — keinen Kapazitätsrechner. Bevor wir eingestiegen sind, wuchs das Team in vierzehn Monaten von 8 auf 20 Personen, während die Runner-Topologie praktisch unverändert blieb: Release-Wochen mit durchgehend roten PRs, Builds, die ewig in Queued hingen, TestFlight zwei Tage zu spät. Im Folgenden erklären wir, warum CI bei mehr Leuten langsamer wird und an welcher Pipeline-Stelle der Engpass sitzt.

Wer wissen will, wie viele Macs man für 500 Builds pro Tag braucht, findet die Antwort im Schwesterartikel 3 Cloud Macs für 500 iOS-Builds pro Tag — das ist die Umsetzung nach unserem Einstieg. Hier geht es umwarum es vorher kollabierte.

Kurzfassung: Wenn CI in einem 20-köpfigen Team zusammenbricht, reicht selten „zu wenig Macs“. In diesem Fall überlagerten sich fünf Engpässe nacheinander: Concurrency ausgeschöpft → Runner konkurrieren mit Entwicklung → PRs laufen Archive → Matrix-Jobs explodieren → Signing-Konflikte. Ab 12–16 Personen gab es Vorzeichen; wer bei 20 noch keine Queues trennt, landet in der Failure Zone.

Auf einen Blick: Wie CI von „mehr Leute“ in die Failure Zone rutscht

Abbildung 1 ist das Übersichtsdiagramm des gesamten Artikels — besser geeignet für Postmortem-Eröffnungen oder Team-Onboarding als Pipeline-Details. Ein Kollaps ist selten ein Einzelpunkt, sondern die Überlagerung der folgenden Kette.

Abb. 1 · CI-Kollaps-Mechanismus (Scaling Failure Cascade)

Steigende PR-Merge-Rateteam scaling · nichtlinearer Start
Matrix / Job-Explosionmonorepo · path filter versagt
Queue-Stauqueue_wait_seconds ↑
Runner-Pool gesättigthosted concurrency · mini belegt
Archive-ÜberlastL2 flutet PR-Queue
Signing / Keychain-Konfliktcodesign contention
Failure Zonequeue P95 > 30min · Archive > 30%

Bei diesem Kunden blieb es bei 12 Personen in der Queue stecken, bei 16 leuchteten Runner/Archive-Abzweigung gleichzeitig, bei 20 landete man unten im roten Bereich. Der Vergleich mit der healthy baseline folgt unten.

iOS CI/CD-Architektur: Engpasskarte von PR bis TestFlight

Abbildung 2 zeigt den Ausführungspfad eines macOS-Jobs (L0/L1/L2) und markiert die beiden Stellen, die in diesem Fall zuerst voll liefen. So erkennt man: Kompilierung langsam — oder der Job läuft gar nicht erst.

Abb. 2 · iOS CI/CD Pipeline: L0 / L1 / L2 und typische Engpässe (Kunde 2024–2025)

PR Pushpath filter · matrix
Queuequeue_wait_seconds
Runner Poolhosted + self-hosted
L0/L1 BuildIntegration · Unit Tests
L2 Archivexcodebuild archive
SigningKeychain · Match
UploadTestFlight
↑ Bottleneck · Queue (Organisations-macOS-Concurrency ausgeschöpft) ↑ Contention · Runner Pool + Signing (Büro-Mac und Keychain konkurrieren)

L0: lint / leichte Checks; L1: PR-Integrationsbuild und Simulator-Tests; L2: Archive, Notarisierung, Upload. Der Kunde kollabierte in Queue und Runner-Mischpool, nicht in L1-Kompilierung — Matrix-Inflation wird oft fälschlich als „Xcode wird langsamer“ gelesen.

Ausgangslage: Warum die CI bei 8 Personen „reichte“, aber nicht mitwuchs

Mitte 2024 sah das Setup typisch aus:

Der CTO sagte wörtlich: „CI ist kein Engpass, verschwendet keine Zeit damit.“ — Bei 8 Personen stimmte das; nach Verdoppelung der Produktivität wurde CI zur unsichtbaren Steuer, weil niemand Kapazität plante und Feature-Teams nur Workflows stapelten.

Healthy baseline: Woran misst man „normal“?

Betrachtet man nur die Kollapswoche bei 20 Personen, vermutet man schnell: „Großes Team = viele Macs kaufen.“ Wir ergänzen einen Vergleich healthy baseline vs. Kollapswoche — Zahlen aus dem 8-Personen-Messfenster des Kunden plus Erfahrungswerte aus mid-size iOS-Teams, die wir betreut haben (kein Branchenstandard, aber ausreichend für interne Reviews).

Metrik Healthy baseline (8–12 Pers. · saubere Topologie) Kunde · Kollapswoche bei 20 Pers.
L1 queue_wait P95 < 8 Min. 47 Min.
L1 run duration P95 12–18 Min. 14 Min. (Kompilierung nicht langsamer)
Anteil Archive-Jobs < 15% 38%
macOS Jobs pro Push · P99 < 6 19
macOS Jobs / Tag 80–180 500+ (Release-Woche)
Runner-Topologie L1/L2 per Label getrennt hosted + Büro-mini gemischt

Entscheidend: In der Kollapswoche blieb run duration fast gleich, queue time stieg fast zehnfach — das Problem lag in Warteschlangen und Workflows, nicht in Xcode-Kompilierung. Genau hier irreführt der Begriff „CI wird langsamer“ am meisten.

Zeitstrahl: Drei Warnungen, dreimal als „Ausreißer“ abgetan

Erstes Mal (12 Personen, +4 iOS): PR-Merges stiegen von 6 auf 14 pro Tag. Die build queue auf gehosteten Runnern zeigte nachmittags 25–40 Minuten Wartezeit. Reaktion: „GitHub spinnt heute wohl.“ Niemand zog die queue_wait_seconds-Kurve.

Zweites Mal (16 Personen, +2 Backend im selben Repo): Im Büro kam ein zweiter Mac mini dazu, beide als self-hosted registriert, ohne Label-Trennung. Archive und PR-Builds teilten sich einen Pool — leichte Jobs sprangen sporadisch von 8 auf 35 Minuten, schwere Jobs scheiterten zufällig bei der Notarisierung. Reaktion: „Kaufen wir noch eine Festplatte.“

Drittes Mal (20 Personen, große Versionen zweier Apps): In der Release-Woche stiegen macOS-Jobs von 120 auf 280+ pro Tag. Im Slack-Kanal #ios-ci war rund um die Uhr jemand im Dienst. Reaktion: „Einkauf prüft 8 Mac minis.“ — Genau das 8-Maschinen-Szenario aus unserem 500-Builds/Tag-Fall; damals hatte noch niemand Job-Aufschlüsselungen gerechnet.

Abb. 3 · Teamgröße vs. macOS Jobs/Tag vs. Risikostufe (Kunde 2024–2025, gemessen)

Teamgröße macOS Jobs / Tag GitHub Actions queue time (L1 P95) Risikostufe Phasennotiz
8 Pers. ~100 < 5 Min. Baseline Ein Büro-mini reichte
12 Pers. ~180 25–40 Min. Warning Zone Queue erstmals dauerhaft über Schwellwert
16 Pers. ~260 ~35 Min. Structural Debt Archive gemischt, Signing sporadisch fehlgeschlagen
20 Pers. 500+ 47 Min. Failure Zone Release-Wochen-Peak, CI faktisch kollabiert
Jobs / Tag 0 200 400 600 100 180 260 500+ 8 12 16 20

Quelle: GitHub Actions Workflow-Logs (14-Tage-Gleitfenster); bei 20 Personen Peak der Release-Woche beider Apps. Job-Volumen wächst schneller als Kopfzahl — hauptsächlich durch Matrix-Inflation und PR-Archive, nicht bloß „mehr Leute“.

Zwei Details in der Tabelle: Zwischen 16 und 20 Personen steigt das Job-Volumen steil, Archive-Anteil von ~18 % auf 38 %; queue time und Job-Volumen sind nichtlinear — die Köpfe verdoppeln sich nicht, die Wartezeit schon. Genau hier verrechnen sich Skalierungsbudgets.

Schwellenmodell: 12 Warning / 16 Structural Debt / 20 Failure Zone

Wir haben den Fall zu einem Framework für Weekly Reviews verdichtet — keine exakte Formel, aber ausreichend, um Runner-Topologie anzufassen:

CI-Kollapsrisiko ∝ (PR-Frequenz × Matrix-Breite × Archive-Anteil) ÷ effektive Runner-Pool-Kapazität

Alle drei Zähler lassen sich aus GitHub Actions-Logs ableiten; der Nenner „effektiver Runner-Pool“ ist nicht die registrierte Maschinenanzahl, sondern gleichzeitig nutzbare Mac-Slots nach Label-Trennung — wenn Entwickler den Büro-mini blockieren, bricht der Nenner sofort ein. Gelten zwei der folgenden Bedingungen gleichzeitig, stoppen wir die Diskussion „noch ein Mac mini“ und refaktorisieren die Pipeline:

  • queue_wait_seconds P95 > 30 Min. und Archive-Jobs > 30 % → L1/L2 trennen, kein vollständiges PR-Archive mehr
  • macOS Jobs pro Push · P99 > 15 → Matrix/path filter außer Kontrolle, erst Jobs reduzieren, dann Hardware
  • L2 queue P95 > 40 Min. an 3 Tagen hintereinander und Cache-Hit > 60 % → strukturelle Skalierung, dedizierter Release-Pool

In der Kollapswoche bei 20 Personen trafen alle drei zu — damit Failure Zone, nicht bloß Warning, die man mit Minutenpaketen wegdrückt.

GitHub Actions queue time: Erste Kennzahl, die ab 12 Personen kippt

Viele Teams lesen „CI wird langsamer“ als langsames Kompilieren und optimieren DerivedData. In den Logs dieses Kunden geriet queue time außer Kontrolle — Jobs blieben lange in Queued. GitHub trennt queue_wait_seconds und run duration; wer nur Letzteres betrachtet, optimiert Kompilierung, während der Engpass in Organisations-Concurrency und Runner-Pools liegt.

Organisationsweite macOS-Concurrency: GitHub Actions usage limits. Ab 12 Personen bei Nachmittags-PR-Stürmen: Runner sind nicht langsam, Jobs warten auf Slots — Queued im UI wird oft Netzwerk oder Xcode zugeschoben. Beim Debuggen Job-Ausführungszeit und Wartezeit trennen.

Bei 12 Personen lag queue P95 schon bei 25–40 Minuten. Hätte man fast/archive per Label getrennt (statt zwei minis gemischt), wäre Signing-Konflikt später gekommen. Runner-Topologie: Entscheidungsmatrix elastischer Pool vs. feste Knoten.

Fünf Skalierungsengpässe (Scaling Taxonomy)

Die folgenden fünf Kategorien sind unsere internen Mobile-CI-Fehlerlabels — passend zu Abb. 2, praktisch für Postmortems.

① Capacity bottleneck · Organisations-macOS-Concurrency ausgeschöpft

Bei voller gehosteter Concurrency warten leichte Jobs und Archive gemeinsam — schnelle Queues werden von langsamen Jobs blockiert, wie in der GitHub Actions queue time-Kurve oben. Statt Minutenpakete: L2 aus dem gehosteten Pool; sonst bleibt Organisations-Concurrency die erste Decke.

② Resource contention · Büro-Mac mini als „Reserve-Entwicklungsrechner“

Runner auf Maschinen, auf die Entwickler per SSH kommen — irgendwann läuft lokal xcodebuild debug. Runner und Alltagsentwicklung konkurrieren um CPU/Disk, Timeouts oder sporadische compile errors folgen. Bei 16 Personen: zwei minis „freitags tot, montags ok“ — Ursache Remote Desktop und Branch-Wechsel.

③ Workflow design debt · Jedes PR führt vollständiges Archive aus

Bei 8 Personen die Abkürzung „grünes PR = releasefähig“: Archive + Upload am Ende jedes pull request workflows. Bei 6 Merges pro Tag noch erträglich; bei 20 Personen stieg der Archive-Anteil von 10 % auf 35 %+ — langsame Jobs fluten die ohnehin volle Queue. Richtig: L1-Integrationsbuild und L2 Archive trennen — erst nach unserem Einstieg umgesetzt, siehe Job-Schichtung im Schwesterartikel.

④ Scaling explosion · Matrix-Jobs im Monorepo wachsen exponentiell

Bei 20 Personen löste ein Push bis zu 22 macOS-Jobs aus — 2,5× mehr Leute, 4× mehr Jobs. Der am leichtesten übersehene Kollapspunkt im Produkt-Takt.

⑤ Crypto / signing contention · Keychain und Signing am Release-Tag

Zwei Self-hosted Macs parallel mit Archive — auf 16 GB RAM sporadisch noch ok; plus Match-Unlock, Notarisierung, TestFlight-Upload werden Keychain-Sperren und codesign-Konflikte zu „derselbe Fehlercode zufällig“. In der Release-Woche vier Mal hintereinander „Zertifikat nicht gefunden“, lokal am Mac ok — typisch für parallele Jobs in derselben Signing-Umgebung, nicht abgelaufenes Zertifikat. Doku: Apple Xcode Signing and Capabilities.

Ihre „Fixes“ — und warum es schlimmer wurde

Mehr GitHub-Minuten kaufen: Entlastet nur gehostete Queues, Archive-Anteil unverändert — Geld ausgegeben, P95 weiter über 60 Minuten.

Dritter Mac mini im Büro: Weiter ohne fast/archive-Labels, drei Maschinen gemischt — Signing-Fehlerrate stieg.

Freitags-Merges verbieten: PR-Frequenz künstlich gedrückt, Release-Woche konzentriert Spitzen noch höher.

timeout-minutes: 180 pro Job: Queued-Zeit zählt nicht zum Timeout — mehr Jobs blockieren lange Slots.

Ein halbwegs wirksamer Versuch blieb unvollendet: Release auf separate Maschine — weiter Büro-mini, nachts niemand für Keychain-Unlock, L2-Queue staut sich montags.

Drei Zahlen, die ins Monitoring gehören — aber fehlten

Vor dem Kollaps zeigte Grafana nur Erfolgsrate und Durchschnittsdauer. In Woche eins nach Einstieg reichten drei Metriken für 80 % der Diagnose (queue_wait_seconds-Aufteilung: GitHub-Monitoring-Doku):

  • queue_wait_seconds P95 (nach L0/L1/L2) — „Kompilierung langsam“ vs. „in der Queue“
  • Anteil Archive-Jobs (wöchentlich) — Workflow-Design außer Kontrolle?
  • macOS Jobs pro Push · P99 — Matrix-Explosion?

Kollapswoche bei 20 Personen: L1 queue_wait P95 47 Min., Archive 38 %, Jobs pro Push P99 19. Zwei Werte über Schwellwert → Topologie anfassen, nicht zuerst Einkauf.

Reihenfolge beim Stoppen der Blutung: Topologie, dann Mac-Anzahl

In den ersten zwei Wochen nach Einstieg: keine neuen Maschinen, vier Maßnahmen:

  • Archive aus PR-Workflow, L2 nur nightly + release branches
  • Path filter enger — README/Backend löst iOS-Matrix nicht mehr aus
  • Büro-mini als Runner abgemeldet, keine Konkurrenz mit Entwicklung
  • Gehostete Runner nur für L1-Spitzen, L2 auf dedizierte Knoten

Nur das senkte queue_wait P95 in der Release-Woche von 47 auf 22 Minuten — noch nicht genug, aber bewies: Hauptursache Topologie und Workflow, kein „mysteriöses Mac-Formel“. Erst danach Cloud-Mac fast/release-Pools und Kapazitätstests; elastischer vs. fester Pool: GitHub Actions Self-hosted macOS Runner: Entscheidungsmatrix.

Drei Signale für wachsende Teams

Wer von 12 Richtung 20 skaliert und eines davon sieht, sollte diese Woche 30 Minuten CI-Review einplanen — nicht auf Release-Kollision warten:

  • Entwickler fragen: „Können wir ohne grünes CI mergen?“
  • Am Büro-Mac klebt „Bitte nicht neu starten, Runner läuft“
  • TestFlight-Build ok, aber „Warten auf Upload-Fenster“ ist Normalzustand

Hinter diesen Signalen stecken meist mindestens zwei der fünf Kollapspunkte oben.

Postmortem Summary (zitierbar)

Root cause

Beim Teamwachstum CI-Topologie nicht mit skaliert: PR-Frequenz und Matrix-Breite stiegen, Runner blieben „hosted + Büro-mini gemischt“, PR-Workflows liefen weiter L2 Archive — queue und signing doppelt gesättigt.

Contributing factors

  • Kein Monitoring von queue_wait_seconds, Queued als langsames Kompilieren missverstanden
  • Zweiter Mac mini ohne fast/archive-Labels, Archive und PR im selben Pool
  • Monorepo path filter zu breit, README-Änderung löst iOS-Matrix aus
  • Release-Wochen-Peaks nicht mit Einkauf/Topologie verknüpft

Fixes tried (wirkungslos oder verschlimmernd)

  • Mehr GitHub-Minuten — nur hosted-Queue, Archive-Anteil gleich
  • Dritter Büro-mini gemischt — Signing-Fehler häufiger
  • Freitags-Merge-Verbot — Spitze in Release-Woche
  • timeout-minutes: 180 — Queued zählt nicht

What worked (erste zwei Wochen nach Einstieg)

  • Archive aus PR; L2 nur nightly + release branches
  • Path filter enger; Büro-mini ohne Runner
  • L2 auf dedizierte Release-Knoten — queue P95 47min → 22min

FAQ

GitHub Actions bleibt in Queued — nicht langsame Kompilierung?

Zuerst queue_wait_seconds und run duration prüfen. Hoher Queued-Anteil → Engpass Queue oder Runner-Pool, nicht Kompilierung. Abb. 2 Queue-Knoten und Abb. 3 healthy baseline zum Abgleich.

Bei wie vielen iOS-Entwicklern bricht CI am ehesten?

In diesem Fall: 12 Warning / 16 Structural Debt / 20 Failure Zone. Zuverlässiger: queue P95 > 30 Min. und Archive > 30 % → Pipeline refaktorisieren.

Beim Wachstum: erst Hardware oder erst Pipeline?

Job-Schichtung, PR-Archive stoppen, Matrix straffen. Sonst verschiebt Hardware den Kollaps nur — queue-Spitzen kommen in der nächsten Release-Woche zurück.

Ist das derselbe Artikel wie „500 Builds/Tag, wie viele Macs“?

Nein. Hier warum der Kollaps (Failure Model); Schwesterartikel Kapazität und Maschinenzahl (Sizing). Erst diesen Artikel + Diagnose, dann Sizing.

Failure Zone-Rezept: erst L2 isolieren, dann Runner-Pool validieren

Alle drei Bedingungen erfüllt → Failure Zone (wie Abb. 1 unten)

  • queue_wait_seconds P95 > 30 Min.
  • Archive-Jobs > 30 %
  • macOS Jobs pro Push > 15

Engineering zuerst (vor Einkauf)

1. L2 isolation — Archive aus PR; release/nightly exklusiv macos-archive-Label.

2. Dedicated Mac pool — L2 raus aus Büro-Entwicklung und hosted-Mischpool; L1 weiter hosted oder elastisch self-hosted für Spitzen.

3. Validierung — Release-Workflow auf isoliertem Knoten, queue P95 gegen Abb. 3 healthy baseline (< 8 Min.).

Maschinenzahl und fast/release-Pool-Logik: 3 Cloud Macs für 500 iOS-Builds pro Tag; elastisch vs. fest: GitHub Actions Self-hosted macOS Runner Entscheidungsmatrix.

Für einen tagesweisen PoC eines release-dedizierten Knotens zur L2-isolation-Validierung: Mac Cloud Hosting oder VPSSpark Startseite — isolierte Archive-Queue auf Cloud Mac. Topologie validieren, nicht sofort volles Cluster kaufen.

Angebot

iOS-CI bei 20 Leuten am Limit? Queues trennen

build queue · Archive-Isolation · Cloud Mac Runner

Zur Startseite
Angebot Tarife ansehen