← Retour au journal

Xcode CI ralentit-il OpenClaw Gateway sur Mac M4 ? Cause swap + Guide de tuning launchd en co-location (2026)

OpenClaw · 2026.06.06 · env. 12 min

Agent de build Xcode et OpenClaw Gateway partageant les ressources sur un même Mac M4

Trois critères de décision pour co-localiser Xcode CI + OpenClaw Gateway sur un Mac M4 :

  • 24 Go est le plancher de production

    16 Go permet 1 build simultané + Gateway en veille, mais la pression mémoire est visible aux pics. Avec 24 Go, 2 builds parallèles restent stables sans déclencher le swap. 32 Go convient aux nœuds CI d'équipe.

    24 Go recommandé

  • Le vrai goulot : swap + dépriorisation du scheduler

    Les ports Xcode et OpenClaw ne sont pas en conflit (20300 vs 18789). Le problème vient du pic de compilation Xcode qui compresse les pages mémoire de Gateway dans le swap, faisant monter la latence de 50ms à 500ms+.

    0 conflit de port

  • ≥3 builds simultanés ou ≥50 builds/jour → séparation

    L'un de ces critères suffit pour migrer Gateway sur un nœud dédié : ≥3 builds simultanés, ≥50 builds/jour, Gateway face aux utilisateurs finaux, artefacts >50 Go/mois.

    ≥50/jour → séparer

Conclusions essentielles (version 30 secondes)

Faire cohabiter Xcode CI et OpenClaw Gateway sur un Mac M4 est techniquement faisable, mais sans ces conditions la latence Gateway grimpe de 50ms à 500ms+ :

  • 24 Go RAM est le minimum de production (16 Go réservé aux machines de dev/expérimentation à faible charge)
  • La compilation parallèle Xcode doit être limitée : 16 Go → 3–4 threads, 24 Go → 4–6 threads, 32 Go → 6–8 threads
  • Le launchd de Gateway doit définir Nice = -5 pour hausser la priorité scheduler et éviter d'être écrasé par Xcode
  • La véritable cause des pics de latence Gateway est le swap, pas la contention CPU
  • Séparation obligatoire si : builds simultanés ≥3 · builds/jour ≥50 · Gateway face aux utilisateurs · swap en croissance continue

1. Xcode CI et OpenClaw Gateway peuvent-ils cohabiter sur le même Mac M4 ?

Sous macOS, l'agent de build Xcode (xcsbuildd) et OpenClaw Gateway (un service Node.js persistant écoutant sur le port 18789) sont fondamentalement des processus indépendants — pas de conflit de port, pas de socket partagé, tous deux gérables simultanément par launchd.

La question n'est pas de savoir s'ils peuvent tourner ensemble, mais s'ils resteront stables. Trois risques cachés :

  • La compilation Xcode sature instantanément tous les cœurs CPU (les 10 cœurs du M4 à plein régime)
  • Un clean build Swift consomme 4–6 Go de RAM
  • Le mécanisme de swap macOS peut faire bondir la latence Gateway de millisecondes à plusieurs secondes
Quatre conditions nécessitant une séparation (une seule suffit)
Gateway sert des utilisateurs externes (pas seulement CI interne) · Builds simultanés ≥3 · Builds/jour ≥50 · Artefacts de build >50 Go/mois

2. Modèle mémoire Mac M4 et goulots CI : 16 Go / 24 Go / 32 Go suffisent-ils ?

Commençons par des bases mémoire réalistes. macOS lui-même consomme environ 3 Go ; OpenClaw Gateway (runtime Node.js, Channels, Dashboard) nécessite une réserve de 800 Mo ; le reste est entièrement dédié aux processus de build Xcode.

La consommation mémoire de Xcode varie significativement selon la taille du projet :

Types de build Xcode et consommation mémoire typique
Type de build Mémoire (unitaire) Remarques
Build incrémental1–2 GoBuilds commit quotidiens ; la plupart des cibles déjà en cache
Projet moyen, complet2–4 Go50–150 fichiers Swift avec dépendances tierces
Clean build4–6 GoPeut atteindre la limite avec Firebase / Realm etc.
2× simultanés8–12 GoDeux builds complets en parallèle
3× simultanés12–18 GoSûr uniquement sur machines 32 Go

Synthèse des capacités de co-location par palier mémoire :

Capacité de co-location M4 Mac mini par palier RAM
Critère 16 Go Config limite, dev/expérimentation 24 Go CI production standard
RAM disponible Xcode≈12 Go≈20 Go
Max builds simultanés recommandé12
Risque swap clean buildÉlevé, fréquentFaible, rare
Jitter latence Gateway1–3s aux picsGénéralement <100ms
Usage recommandéCI faible charge / Gateway interneCI production + Gateway interne

Une machine 32 Go peut exécuter 3 builds simultanés en toute sécurité sans aucun impact sur Gateway — idéale pour les nœuds CI d'équipe.

3. Xcode CI et OpenClaw Gateway ont-ils des conflits de ports ? Tableau complet de topologie des processus

La première étape d'une co-location est de confirmer les ports, noms de processus et labels launchd de chaque service — pour établir une base de référence pour la configuration des priorités et le diagnostic d'incident.

Inventaire complet processus, ports et labels launchd pour Xcode Server + OpenClaw Gateway
Processus Service Port Label launchd Remarques
xcsbuilddXcode Server20300 (HTTPS)com.apple.xcs.buildserviceCoordinateur de build, reçoit les tâches CI
xcsdXcode Server20343com.apple.xcs.xcsdDémon principal Xcode Server
buildagentdXcode— (socket Unix)Agent de build local
openclaw-gatewayOpenClaw18789 (HTTP/WS)com.openclaw.gatewayProcessus principal Gateway + Dashboard
openclaw-agentOpenClaw— (sortant)com.openclaw.agentEnregistrement Channels (optionnel)
bash — Vérifier l'absence de conflit de ports (vérification de base obligatoire)
sudo lsof -iTCP:20300 -sTCP:LISTEN   # Xcode Server
sudo lsof -iTCP:18789 -sTCP:LISTEN   # OpenClaw Gateway

# Voir les processus des deux services en une fois
ps aux | grep -E 'xcsd|xcsbuildd|openclaw' | grep -v grep

4. Tuning launchd + scheduler CPU : empêcher Xcode d'évincer Gateway

macOS launchd contrôle la priorité des processus via la clé Nice dans les fichiers plist (valeur basse = priorité haute ; plage −20 à 20, défaut 0). La stratégie centrale en co-location : donner à Gateway une priorité plus élevée tout en limitant les threads de compilation parallèle de Xcode — pas de conteneurs, pas de virtualisation, uniquement les mécanismes natifs launchd.

Étape 1 : Augmenter la priorité scheduler de Gateway

xml — /Library/LaunchDaemons/com.openclaw.gateway.plist (ajouter la clé Nice)
<!-- Insérer dans <dict> pour que Gateway soit schedulé avant Xcode -->
<key>Nice</key>
<integer>-5</integer>

Étape 2 : Limiter les threads de compilation parallèle Xcode (par palier RAM)

bash — Définir la parallélisme Xcode par palier RAM
# Machine 16 Go : recommandé 3–4 (30–40% des 10 cœurs M4)
defaults write com.apple.dt.Xcode \
    IDEBuildOperationMaxNumberOfConcurrentCompileTasks 4

# Machine 24 Go : recommandé 4–6
# defaults write com.apple.dt.Xcode \
#     IDEBuildOperationMaxNumberOfConcurrentCompileTasks 5

# Machine 32 Go : recommandé 6–8
# defaults write com.apple.dt.Xcode \
#     IDEBuildOperationMaxNumberOfConcurrentCompileTasks 7

# Vérifier la valeur actuelle
defaults read com.apple.dt.Xcode \
    IDEBuildOperationMaxNumberOfConcurrentCompileTasks

Étape 3 : Recharger le plist Gateway pour appliquer Nice

bash — Recharger et vérifier la valeur Nice
sudo launchctl unload /Library/LaunchDaemons/com.openclaw.gateway.plist
sudo launchctl load   /Library/LaunchDaemons/com.openclaw.gateway.plist

# Confirmer que la valeur nice est -5
ps -o pid,nice,comm -p $(pgrep -f openclaw-gateway)

5. Pourquoi le swap fait monter la latence Gateway de 50ms à 500ms — et comment le surveiller

Contrairement à Linux, macOS ne tue pas les processus par OOM-Kill. Il comprime plutôt les pages mémoire inactives (Compressed Memory) et les écrit dans le swap SSD. Cela évacte silencieusement le heap de Gateway ; le surcoût CPU et d'attente I/O lors de la décompression au prochain accès est la cause directe des pics de latence.

Pendant un pic de build Xcode, ouvrir une deuxième session SSH et exécuter cette surveillance à trois niveaux :

bash — Surveillance à trois niveaux : pression mémoire + latence Gateway
# Niveau 1 : pression mémoire système (métrique clé)
memory_pressure
# Normal   → sûr
# Warn     → latence Gateway commence à fluctuer ; réduire la parallélisme
# Critical → réduire immédiatement de moitié le parallélisme Xcode

# Niveau 2 : snapshot vm_stat ; surveiller la colonne compressed
vm_stat | grep -E 'Pages (wired|active|inactive|compressed|free)'

# Niveau 3 : sonde en temps réel de la latence de réponse Gateway
while true; do
  ms=$(curl -o /dev/null -s -w "%{time_total}" http://localhost:18789/health)
  echo "$(date +%H:%M:%S)  gateway=${ms}s"
  sleep 5
done

Règle de décision : si memory_pressure indique Warn et que la latence Gateway dépasse 200 ms, choisir l'une des options suivantes : réduire le parallélisme Xcode → upgrader vers un palier RAM supérieur → migrer Gateway sur une machine dédiée.

6. Modèle de décision de séparation en production : quand faut-il séparer le CI Mac M4 en deux machines ?

Le plafond de co-location est quantifiable. Migrer Gateway vers un nœud dédié dès qu'un de ces critères s'applique :

  • Builds/jour ≥ 50 — la pression mémoire cumulée provoque des fluctuations périodiques de Gateway aux heures de pointe.
  • 3+ builds simultanés nécessaires — trois builds complets en simultané poussent la mémoire disponible à la limite sur une machine 24 Go.
  • Gateway sert des utilisateurs finaux (pas seulement CI interne) — les clients mobiles connectés directement à Gateway ressentent immédiatement tout jitter de latence.
  • Artefacts de build > 50 Go/mois — la contention I/O disque dégrade à la fois les écritures de logs Gateway et le débit de build.

Solution de séparation à coût minimal : un second M4 16 Go dédié à Gateway (mémoire résidente ~500 Mo ; 16 Go largement suffisant), la machine originale conservée pour les builds Xcode. Connexion via Tailscale (<5 ms de latence LAN) sans modification de la topologie réseau existante. Pour la configuration et le runbook opérationnel après séparation, consultez : OpenClaw 2026 : installation, déploiement et dépannage sur Mac distant — openclaw onboard, démon Gateway et planification des ressources M4 au Canada.

7. FAQ : co-location Xcode CI + Gateway sur Mac M4

Q1 : Xcode et un service Node.js (OpenClaw Gateway) s'interfèrent-ils sur Mac M4 ?

Oui — principalement via le swap mémoire et la priorité scheduler, pas par contention CPU directe. Un build Xcode complet consomme instantanément 4–6 Go de RAM, forçant macOS à compresser les pages mémoire du Gateway (priorité basse sans Nice) dans le swap. Le délai d'attente I/O lors de la décompression est la cause directe du saut de latence de 50ms à 500ms. Définir Nice=-5 pour Gateway atténue significativement ce phénomène.

Q2 : Pourquoi la latence Gateway monte-t-elle soudainement de 50ms à 500ms ?

La cause racine est la Compressed Memory macOS : quand un build Xcode sature la RAM, les pages mémoire anonymes de Gateway sont compressées et écrites dans le swap SSD. Lors du prochain accès de Gateway à ces pages, il doit attendre la décompression CPU + lecture SSD — cet aller-retour produit les centaines de millisecondes de latence. La commande memory_pressure permet de surveiller les niveaux de pression en temps réel (Normal / Warn / Critical).

Q3 : Quel nombre de threads de compilation parallèle Xcode est le plus stable ?

Par palier RAM : 16 Go → 3–4 threads (30–40% des 10 cœurs M4), 24 Go → 4–6 threads, 32 Go → 6–8 threads. Commande : defaults write com.apple.dt.Xcode IDEBuildOperationMaxNumberOfConcurrentCompileTasks 5 (exemple 24 Go). Après application, déclencher un build et vérifier que la latence Gateway reste sous 100 ms avant d'affiner.

Q4 : Que fait concrètement launchd Nice=-5 ?

Une valeur Nice plus basse signifie que le scheduler macOS alloue davantage de tranches CPU au processus, et que ses pages mémoire sont compressées plus tardivement sous pression. Régler Gateway à Nice=-5 (Xcode par défaut à 0) donne à Gateway la priorité scheduler lors de la contention CPU, et son heap est évacué vers le swap plus tard que les processus de compilation Xcode — préservant ainsi la vitesse de réponse Gateway.

Q5 : Quand faut-il absolument séparer les machines ? Quelles conditions rendent la co-location impossible ?

Migrer Gateway vers un nœud dédié dès qu'un de ces critères s'applique : ① builds simultanés ≥3 ; ② builds/jour ≥50 ; ③ Gateway est face aux utilisateurs finaux (mobile connecté directement, pas seulement CI interne) ; ④ memory_pressure reste à Warn ou Critical pendant les heures de travail et Pages compressed ne récupère pas. Séparation minimale : ajouter un M4 16 Go pour Gateway, Tailscale (<5 ms).

Q6 : Un Mac M4 16 Go peut-il faire tourner Xcode CI et OpenClaw Gateway en production simultanément ?

Oui, mais sous conditions strictes : ① limiter les builds simultanés à 1 ; ② Gateway uniquement pour CI interne (pas exposé à l'externe) ; ③ maintenir le nombre de builds quotidiens sous 20. Dans cette configuration, memory_pressure reste Normal la plupart du temps et la latence Gateway fluctue occasionnellement mais récupère généralement sous <300ms. Si les conditions sont dépassées, passer immédiatement à 24 Go ou séparer.

Nœuds dédiés — l'aboutissement naturel de la co-location

Quand le volume de builds nécessite une séparation, ajouter un Mac mini M4 dédié Hashvps Canada est le chemin de mise à l'échelle le plus économique : un nœud Gateway n'a besoin que de 16 Go (mémoire résidente ~500 Mo), tandis que le nœud builder peut être 24 Go ou 32 Go selon les besoins. Les deux machines se connectent via Tailscale avec <5 ms de latence et aucune modification de la topologie réseau existante. La consommation en veille du M4 Mac mini est d'environ 4 W — les coûts d'électricité pour un fonctionnement 7×24 sont négligeables, bien inférieurs aux coûts d'exploitation de serveurs x86 équivalents. Si vous planifiez de migrer votre Xcode CI et OpenClaw vers un matériel stable et prévisible, consultez les offres disponibles ci-dessous.

Hashvps · Mac Cloud

Une machine pour les builds, une pour Gateway — stabilité garantie

Mac mini M4 dédié au Canada. macOS bare-metal, 16 Go / 24 Go / 32 Go à la demande, réseau privé Tailscale.

Voir les offres
Offre limitée