Anfang Juni packten wir Xcode CI und OpenClaw Gateway auf dieselbe kanadische M4-Maschine und hielten zwei Wochen durch — mit launchd Nice=-5 und begrenzter Build-Parallelität. Ab Woche drei meldeten Kollegen im IM: „Gateway hängt wieder.“ Die Build-Logs wirkten normal, doch der curl-Health-Check driftete in Spitzen von 50 ms auf über 400 ms. Wir senkten Parallelität, leerten DerivedData, buchten kurzzeitig 24 GB — das Problem ging von „zweimal täglich“ auf „einmal täglich“, blieb aber.
Das war kein Konfigurationsfehler, sondern das Same-Host-Ressourcenmodell am Limit. Ports kollidieren nicht (20300 vs. 18789), CPU-Kerne reichen — der Konflikt sitzt in Unified Memory und Swap. Dieser Artikel folgt auf Co-Location und launchd-Tuning: wann Dual-Node Pflicht wird, wie die Topologie aussieht und wie Sie Traffic umschalten, ohne Channels zu zerlegen. Offizielle Hinweise zu Speicher und Build-Verhalten: Apple-Dokumentation zu Xcode-Build-Cache; Tailscale-Setup: Tailscale-Installationsanleitung.
Kurz gesagt: Die Wasserscheide ist Ressourcenisolierung, nicht „noch eine Maschine kaufen“.
-
Vier harte Signale — eines reicht zum Split
≥50 Builds/Tag, ≥3 parallele Pipelines, Gateway für Endnutzer oder ≥3× Critical-Swap pro Woche — weiteres Nice-Tuning verschiebt nur den Termin.
≥50/Tag
-
Minimales Dual-Node: Build-Host + Gateway-Dedicated
Build-Knoten 24 GB+ und große SSD; Gateway-Knoten 16 GB reichen für ~500 MB Dauerlast. Zwei M4 über Tailscale; öffentlich nur nötige Eingänge.
16 GB Gateway
-
Migration = Zustand + DNS, nicht Neuinstallation
rsync der Config, Token wiederverwenden, Tailscale MagicDNS umschalten; Build-Host läuft weiter, Gateway Blue/Green ≤15 Minuten.
Blue/Green ≤15 min
1. Warum Same-Host plötzlich nicht mehr reicht
Viele Teams starten mit einem Cloud-Mac für drei Rollen: xcodebuild, OpenClaw Gateway auf 18789, gelegentlich VNC für Keychain. Bei wenig Last wirken 16 GB großzügig. Mit mehr Branches, parallelen UI-Tests und Channels von internem Pilot zu Produktions-IM wird die Speicherkurve von „Sägezahn“ zu „Plateau“ — zehn Minuten nach Build-Ende bleiben komprimierte Seiten über 8 GB, Gateway-Heap rutscht weiter in Swap.
Same-Host-Tuning (weniger Parallelität, höheres Nice, Cache leeren) senkt die Wahrscheinlichkeit überlappender Peaks, eliminiert Peaks nicht. Wenn APAC-Tagesbuilds und nordamerikanische Abend-IM-Spitzen fast sicher kollidieren, optimieren Sie nicht mehr Parameter — Sie wetten auf den Scheduler. Apple Silicon hat keinen separaten VRAM-Puffer; Xcode und Node.js-Gateway teilen denselben physischen Pool. Ab memory_pressure Warn spüren Nutzer Latenz-Jitter; CI sieht sporadische Timeouts und Signatur-Fehler.
Split bedeutet nicht „Mythos Skalierung“, sondern nicht komprimierbare Peaks trennen: Build-Spitzen nur auf dem Build-Knoten, Gateway-RAM nie von xcsbuildd verdrängt. Das entspricht der Logik in GitHub Actions Self-hosted macOS Runner auf Cloud Mac — dedizierter Runner ohne Desktop-Mix — hier getrennt werden Gateway und CI.
Für DACH-Teams mit dokumentierten SLAs ist der Moment oft nicht der erste Swap, sondern der dritte IM-Vorfall in einer Woche, bei dem Logs „grün“ sind, Nutzer aber „Gateway hängt“ melden. Dann ist Same-Host keine Kosteneinsparung mehr, sondern versteckte Ausfallzeit.
Ein hilfreiches Gedankenexperiment: messen Sie Gateway-P95 nur während aktiver xcodebuild-Jobs. Steigt die Latenz um Faktor 3–8, obwohl CPU-Auslastung unter 70 % bleibt, haben Sie kein Netzwerkproblem — Sie haben Speicher-Konkurrenz. In unserem Fall lag compressed memory nach dem Build noch zehn Minuten über 6 GB; der Node.js-Heap des Gateways konnte nicht stabil resident bleiben. Jeder Versuch, mit Nice oder weniger -jobs zu reagieren, senkte den Build-Durchsatz, ohne den Gateway-SLA zu retten. Das ist der klassische Same-Host-Falleffekt: zwei Teams optimieren gegeneinander auf derselben Maschine.
Wer bereits Self-hosted Runner auf Cloud Mac betreibt, kennt die Regel „kein Desktop, kein Gateway auf dem Runner“. Der Dual-Node-Split ist dieselbe Regel, nur dass Gateway hier kein Nebenprodukt, sondern produktionskritischer Dienst ist. Der Unterschied zu „einfach 32 GB buchen“: mehr RAM hebt die Decke für beide Peaks gleichzeitig, trennt sie aber nicht. Wenn der Build-Peak weiterhin 18–22 GB braucht, bleibt für Gateway nur der Rest — und bei parallelen UI-Tests ist der Rest zu klein.
2. Drei Topologien: Same-Host, Dual-Node, Triple-Node
Erst klassifizieren, dann kaufen:
- T0 Same-Host: Ein M4 für Xcode Server / Self-hosted Runner + Gateway. Für <30 Builds/Tag, internes Gateway, tolerierbare Latenz-Spitzen.
- T1 Dual-Node (Fokus): Knoten A nur CI (24 GB+, große SSD); Knoten B nur Gateway (16 GB). Tailscale oder Rechenzentrum-LAN; Channels/Dashboard → B, Build-Trigger → A.
- T2 Triple-Node: Zusätzlich Signatur/Upload- oder paralleler Test-Host. Ab >150 Builds/Tag oder harter Trennung TestFlight/Compile; für die meisten Teams reicht T1.
Asymmetrische These: Nicht M4-Leistung fehlt, sondern zwei SLA-Klassen teilen sich einen Speicherpool. Gateway braucht 99,9 % stabile Antwort; CI braucht Durchsatz. Same-Host kompromittiert beide mit einem SLA.
3. Same-Host vs. Dual-Node vs. Upgrade: Vergleich
| Dimension | Weiter tunen Nice / weniger Parallelität | Einzelhost 32 GB Mehr RAM, gleiche Topologie | Dual-Node-Split CI + Gateway getrennt |
|---|---|---|---|
| Wurzelursache | Peak-Überlappung mildern | RAM-Decke heben | Zwei SLAs isolieren |
| Gateway-Latenz | Schwankt mit Builds | Besser, nicht weg | Build-Zeit <100 ms möglich |
| Monatskosten (grob) | Niedrigst | Mittel (Upgrade) | Mittel (+16 GB Kleinhost) |
| Ops-Aufwand | Niedrig | Niedrig | Mittel (+1 Host, Tailscale) |
| Passende Phase | <30 Builds/Tag | 2 parallele Jobs, internes GW | ≥50/Tag oder externes GW |
| Signal | Schwelle | Beobachtung | Falsch positiv |
|---|---|---|---|
| Build-Frequenz | ≥50/Tag | CI-Logs / Runner-Zähler | Manuelles lokales Archive ausschließen |
| Parallelität | ≥3 volle Builds | xcodebuild -jobs, Queue-Tiefe | Leichtes Lint zählt nicht |
| Gateway-Publikum | Endnutzer / 7×24 Channels | Produkt-SLA | Reiner interner Webhook kann warten |
| Speicherdruck | ≥3× Critical/Woche | memory_pressure-Logs | Einmal-Leak zuerst fixen |
| Disk-Konkurrenz | >50 GB/Monat + hoher I/O wait | df -h + iostat | Archive aufräumen, dann bewerten |
4. Szenarien: Entscheidungsmatrix
- Zwei-Personen-Team, <20 Builds/Tag, Gateway nur intern: T0, launchd-Tuning reicht.
- APAC-Builds, Gateway für IM-Nutzer: direkt T1. Follow-the-sun überlappt Peaks fast sicher.
- GHA Cloud Runner live, Gateway neu: Runner auf A, Gateway auf B; 18789 nicht auf dem Runner-Host.
- TestFlight-Upload vs. Compile um Disk: erst T1; bei Bedarf T2 Signatur-Host — nicht mit diesem Runbook verwechseln.
- Budget nur für einen Host: Gateway-SLA priorisieren, Builds nachts oder weniger parallel — Kompromiss, keine Dauerarchitektur.
Wenn Ihr Incident-Review zeigt, dass P95-Latenz nur während xcodebuild steigt, ist das kein Netzwerkproblem — es ist Speicher-Konkurrenz. T1 adressiert genau das, ohne die Build-Pipeline zu pausieren.
Für verteilte Teams mit Follow-the-sun gilt: selbst wenn Sie nachts in Nordamerika batchweise archivieren, bleibt der Gateway tagsüber für Agent-Sessions und IM-Channels aktiv. Die Wahrscheinlichkeit, dass ein Release-Build mit einem Produktions-Incident überlappt, steigt mit jedem neuen Feature-Branch. T0 funktioniert, solange Gateway „best effort“ ist; sobald Product einen Response-Time-SLA in Confluence verlinkt, sind Sie faktisch in T1-Pflicht — nur ohne zweite Maschine.
Budget-Einwand „nur eine Maschine“: priorisieren Sie Gateway-SLA und verschieben Sie Builds in Nachtfenster. Das ist ein Übergang, kein Zielbild. Innerhalb von 4–8 Wochen sehen wir typischerweise wieder dieselben Tickets, weil Commit-Frequenz steigt. Planen Sie von Anfang an den zweiten Knoten als 16 GB-Gateway-Host ein; der ROI kommt aus weniger Support-Zeit, nicht aus der absoluten Monatsmiete.
5. Empfohlene Stacks (kombinierbar)
- Minimales Dual-Node: Hashvps Kanada M4 24 GB (A, CI) + M4 16 GB (B, Gateway) + Tailscale tailnet + wöchentlich
openclaw doctor. Standard-Upgrade von T0. - CI-Hybrid: A mit Self-hosted Runner für GitHub Actions; B mit Gateway + Channels. Orchestrierung in GitHub, Ausführung auf macOS, Gateway ohne Build-Peaks. Entspricht „Umgebungssouveränität“ in macOS-Build-Markt 2027.
- Observability: Auf B Gateway-Latenz-Probe (
curlalle 5 s) + auf A nach Build-Endememory_pressure-Snapshot; zwei Wochen Daten reichen für Split-ROI gegenüber Management.
6. Typische Fehler vor der Migration
- Erst CI stoppen, dann Gateway ziehen: CI-Stopp ist teuer; Gateway Blue/Green, CI läuft.
- Neuinstallation statt rsync: Verlust von
~/.openclaw, Token, Channel-Pairing → alle müssen neu anmelden. - Zwei öffentliche IPs mit 18789: Während Cutover Tailscale oder internes DNS — nie zwei Gateways parallel an Channels.
- Gateway auf Build-Host zu früh löschen: Rollback-Fenster: alter Prozess bleibt, nur DNS ändert sich.
- Uhrzeit und Zertifikate: NTP-Drift >30 s → sporadische Token-Fehler; Migrationstag
sudo sntp -sS time.apple.com.
7. Runbook: Dual-Node in sieben Schritten
Annahme: bisher mac-ci-01 mit CI+Gateway; neu mac-gw-02 (16 GB) nur Gateway. Tailscale installiert (siehe OpenClaw Ops Runbook).
Schritt 1: Baseline (Tag vor Migration)
Gateway P50/P95, Build-Anzahl, memory_pressure erfassen. openclaw status und Channel-Liste sichern.
# 延迟采样 60 次
for i in $(seq 1 60); do
curl -o /dev/null -s -w "%{time_total}\n" http://127.0.0.1:18789/health
sleep 5
done | sort -n | awk '{a[NR]=$1} END{print "p50="a[int(NR*0.5)],"p95="a[int(NR*0.95)]}'
memory_pressure
vm_stat | head -8
Schritt 2: Neuer Host + Tailscale
Auf mac-gw-02: macOS-Update, Homebrew, Node, Tailscale; Ping zu mac-ci-01 <5 ms. Kein xcodebuild auf B.
Schritt 3: rsync Gateway-Zustand (Wartungsfenster)
# 在原机 mac-ci-01 执行;先停 Gateway 避免写入分裂 sudo launchctl unload /Library/LaunchDaemons/com.openclaw.gateway.plist rsync -avz --delete \ ~/.openclaw/ \ builder@mac-gw-02.tailnet-abc.ts.net:~/.openclaw/ # 同步 launchd plist scp /Library/LaunchDaemons/com.openclaw.gateway.plist \ builder@mac-gw-02.tailnet-abc.ts.net:/tmp/
Schritt 4: Gateway auf neuem Host starten
sudo cp /tmp/com.openclaw.gateway.plist /Library/LaunchDaemons/ sudo launchctl load /Library/LaunchDaemons/com.openclaw.gateway.plist openclaw doctor curl -s http://127.0.0.1:18789/health sudo lsof -iTCP:18789 -sTCP:LISTEN
Schritt 5: Traffic — MagicDNS oder Reverse Proxy
Team-Gateway-Hostname (z. B. gateway.tailnet-abc.ts.net) auf neuen Host; Mobile/Channels auf neuen MagicDNS-Namen. Nicht Gateway auf Alt-Host während Cutover neu starten.
Schritt 6: Build-Host entlasten
Nach erfolgreichem Channel-Test auf B: Gateway launchd auf A entfernen, CI-Parallelität auf 5–6 (24 GB).
# mac-ci-01:确认已无流量打到 18789 后
sudo launchctl unload /Library/LaunchDaemons/com.openclaw.gateway.plist
sudo mv /Library/LaunchDaemons/com.openclaw.gateway.plist \
/Library/LaunchDaemons/com.openclaw.gateway.plist.bak
defaults write com.apple.dt.Xcode \
IDEBuildOperationMaxNumberOfConcurrentCompileTasks 6
Schritt 7: 48 Stunden beobachten + Rollback
.openclaw-Backup und plist.bak sieben Tage behalten. Bei P95 >200 ms oder Channel-Ausfall: DNS zurück, altes plist laden — CI-Queue unberührt. Details: OpenClaw Remote-Mac-Onboarding.
Während der Beobachtungsphase laufen Builds bewusst weiter: Sie wollen sehen, ob der Build-Knoten unter höherer Parallelität stabil bleibt, während Gateway-P95 auf B flach bleibt. Vergleichen Sie die Baseline aus Schritt 1 mit den gleichen Stundenfenstern nach der Migration. Typischer Erfolg: Critical memory_pressure auf A kann weiter vorkommen, aber nur noch während Builds — nie mehr korreliert mit Gateway-Latenz auf demselben Host, weil es keinen gemeinsamen Host mehr gibt.
8. FAQ
F1. Nur 16 GB — logische Rollen ohne zweiten Host?
Ersetzt keinen physischen Split. Zeitverschiebung (nachts bauen, tags Gateway) hilft kurz; bei Follow-the-sun oder 7×24 Channels kollidieren Peaks wieder. Logische Trennung lohnt als Beweis für Beschaffung: Latenz nach Gateway-Move messen.
F2. Muss Dual-Node Tailscale nutzen?
Nein, aber stark empfohlen. Anbieter-LAN, WireGuard oder SSH-Tunnel gehen auch; Tailscale bringt MagicDNS, ACLs, wenig Ops. Zwei Hashvps M4 in Kanada: RTT oft <2 ms — reicht für Build-Webhooks von B nach A.
F3. Dual-Node vs. einzelner 32 GB-Host?
Preis ähnlich: oft 24 GB Build + 16 GB Kleinhost vs. 32 GB Solo. Entscheidend ist nachweisbarer Gateway-SLA; externe Teams rechnen mit Ausfallminuten, nicht nur Monatsmiete.
F4. GHA gehosteter Runner — trotzdem eigener Mac?
Umgebungssouveränität. Gehostetes macOS pro Minute für Spitzen; Self-hosted Cloud Mac ab festen >50 Builds/Tag mit Keychain/DerivedData-Kontrolle. Gateway bleibt unabhängig vom Runner-Modell.
F5. Schnellster Rollback?
DNS zurück + launchctl load auf Alt-Host. Am Rollback-Tag keine Massen-Builds; erst Health + eine Channel-Nachricht, dann CI freigeben. Doppelte Zustandskopien bis Metriken stabil.
F6. Welche Metriken beweisen den Split gegenüber dem Management?
Zwei Wochen reichen. Führen Sie parallel auf dem Alt-Setup Gateway-P95 und memory_pressure-Critical-Events; nach Migration dieselben Metriken auf getrennten Hosts. Wenn P95 während Build-Spitzen von 400 ms auf <100 ms fällt und Critical-Events auf dem Gateway-Host null bleiben, ist der Business-Case klarer als jede CPU-Upgrade-Rechnung. Dokumentieren Sie außerdem „vermiedene Build-Wartezeit“: höhere Concurrent-Compile-Tasks auf 24 GB ohne Gateway-Risiko.
9. Fazit
Mac M4 CI-Split ist kein Scheitern, sondern die nächste Stufe nach erfolgreichem Same-Host-Tuning: Build und Gateway sind beide nötig, aber nicht mehr im selben RAM. Vier harte Signale, T1 für SLA-Trennung, sieben Schritte Blue/Green — die Wasserscheide ist Isolierung, nicht Maschinenzahl.
Stecken Sie in „Gateway hängt, Build darf nicht stoppen“, ist ein 16 GB Gateway-Dedicated-Host der pragmatischere Fix als weiteres Nice-Tuning. Builds auf 24 GB Cloud, Agent und Nutzer auf stabilem 18789 — das ist 2026 die bezahlbare Quasi-Produktions-Topologie für kleine Teams.
Dual-Node-Split mit zwei Cloud Mac mini
Nach dem Split braucht der Build-Host 24 GB und große SSD für DerivedData; der Gateway-Host kommt mit 16 GB für 7×24 niedrige Latenz. Hashvps Kanada M4 Bare Metal, dedizierte IPv4, SSH/VNC sofort — zwei Hosts in einer Region, niedrige Tailscale-Latenz, idealer T1-Einstieg, oft besser als hartes 32 GB-Upgrade auf einem Host.
Planen Sie den Wechsel von Same-Host zu Dual-Node, ist Hashvps Cloud Mac mini M4 ein starker Start für den zweiten Knoten — Tarife ansehen und CI mit Gateway sauber trennen.