Conclusion d’abord : pour la plupart des « grands projets iOS » (multi-modules, mix CocoaPods/SPM, équipes qui poussent sur main chaque jour), le Mac mini M4 10 cœurs + 24 Go de mémoire unifiée est en 2026 le meilleur nœud de compilation — archive complète à froid P50 environ 11–14 minutes, builds incrémentaux 2–4 minutes ; en runner CI pur sans GUI, 16 Go suffisent souvent, à condition de limiter les simulateurs parallèles.
Quatre phases vraiment gourmandes : ① parallélisme swift-frontend multi-targets ; ② finalisation LTO / bitcode du linker ; ③ lectures aléatoires DerivedData et ModuleCache ; ④ swap et throttling thermique en cas de mémoire insuffisante.
Piège fréquent : blâmer le M4 pour des builds lents tout en vidant le disque à chaque job CI — une DerivedData persistante rapporte souvent plus qu’un passage au M5. Modèle d’exploitation : guide d’accélération self-hosted.
Dès qu’une équipe dépasse 500 fichiers Swift, 80 pods et 30+ exécutions CI par jour, les achats se demandent : le Mac mini M4 suffit-il ? Faut-il un M4 Pro ? Attendre le M5 ? Sur les clusters M4 bare metal Nuvcloud, nous avons comparé pendant deux semaines trois projets clients réels (anonymisés) : mêmes paramètres xcodebuild, Xcode 16.4 stable, même stratégie de chemin DerivedData. Ci-dessous : méthodologie reproductible et données d’échantillon — pas un benchmark de labo ; validez avec votre propre dépôt.
1) Définition : qu’est-ce qu’un « grand projet iOS » ?
« Grand » n’a pas de standard unique. Nous classons les clients Nuvcloud en quatre niveaux ; les données ci-dessous concernent surtout le niveau L :
| Niveau | Profil typique | Archive à froid P50 (M4 16 Go) |
|---|---|---|
| S · petit/moyen | <150 fichiers Swift, surtout SPM, pas de pods C++ lourds | 4–6 min |
| M · moyen | 150–400 fichiers, CocoaPods + 2–3 extensions | 7–10 min |
| L · grand | 400+ fichiers, 10+ modules / multi-targets, coque Flutter/RN | 11–16 min |
| XL · très grand | Monorepo, apps white-label, LTO complet | 18–28 min (scinder le projet ou ajouter un runner) |
En niveau L ou XL, si vous exigez indexation Xcode + tests UI simulateur en parallèle, la mémoire devient souvent le goulot avant le modèle de CPU — plus souvent sous-estimé qu’un changement de génération de puce.
2) Puce M4 : pour compiler, ce n’est pas le GPU mais le parallélisme CPU et la bande passante mémoire
Mac mini M4 (2024, base) : CPU 10 cœurs (4 performance + 6 efficacité), GPU 10 cœurs, mémoire unifiée à partir de 16 Go (24 Go / 32 Go en option). Pour xcodebuild :
- Les cœurs performance portent
swift-frontendet clang — Xcode sature les cœurs performance disponibles ; les cœurs efficacité aident au prefetch I/O et à l’indexation en arrière-plan. - Mémoire unifiée = tas compilateur + working set linker + ModuleCache — 16 Go suffisent souvent en « compile only » sans simulateur ; avec
xcodebuild testet simulateur iOS 18, la courbe mémoire grimpe fort. - Le débit séquentiel SSD n’est pas le goulot, l’I/O aléatoire oui — DerivedData contient des dizaines de milliers de petits fichiers ; le NVMe du Mac mini suffit pour les grands projets, mais au-delà de 85 % de remplissage le P99 se dégrade nettement.
- GPU et Neural Engine contribuent peu à la compilation pure ; conversion Core ML et shaders Metal utilisent le GPU.
Face au M3, le M4 gagne environ 15 % en Geekbench mono-cœur ; sur un link fully parallelisé, la sensation est plutôt 10–20 %. Le guide d’efficacité de build d’Apple recommande toujours le découpage modulaire — le matériel ne corrige pas les dépendances circulaires.
3) Méthode : trois machines, deux projets, une commande
Matériel (secteur, macOS 15.5, veille auto désactivée) :
- A : Mac mini M4 10 cœurs / 24 Go / SSD 512 Go (Nuvcloud bare metal, datacenter)
- B : Mac mini M2 Pro 10 cœurs / 16 Go / SSD 512 Go (client, bureau)
- C : MacBook Pro M3 Pro 11 cœurs / 18 Go / 1 To (client, sur secteur)
Échantillons de projets :
- Proj-α (niveau L) : UIKit + SwiftUI, 86 CocoaPods, un scheme Archive, ~520 fichiers Swift
- Proj-β (L+) : modulaire + 2 extensions + module Flutter, ~680 fichiers Swift/ObjC
Commande unique (Release / appareil / sans tests) :
xcodebuild -workspace App.xcworkspace -scheme App -configuration Release -destination 'generic/platform=iOS' -derivedDataPath ~/Build/DerivedData clean archive (à froid avec clean ; incrémental sans clean et même chemin DerivedData)5 exécutions, P50, premier run exclu (préchauffage cache disque). Température et réseau n’affectent pas le segment de compilation locale, mais pod install — chiffres ci-dessous hors téléchargement de dépendances.
4) Archive complète à froid : où le M4 gagne
Proj-α à froid P50 (secondes → minutes) :
| Machine | compile | link | Total |
|---|---|---|---|
| M4 24 Go (A) | 548 s | 142 s | ~11.5 min |
| M2 Pro 16 Go (B) | 672 s | 178 s | ~14.2 min |
| M3 Pro 18 Go (C) | 598 s | 155 s | ~12.6 min |
Proj-β (avec Flutter) creuse l’écart : M4 P50 ~15.8 min, M2 Pro ~20.4 min. ios/Flutter et les targets Xcode natifs se disputent le CPU ; 24 Go laissent le M4 quasi sans swap, le M2 Pro 16 Go subit parfois une pression mémoire en phase link, P99 jusqu’à 24 min.
5) Builds incrémentaux : le vrai terrain du M4
Environ 80 % des builds quotidiens ne touchent que quelques fichiers. Avec DerivedData conservée, Proj-α, 1 fichier Swift modifié, archive incrémentale P50 :
| Machine | Incrémental P50 | Remarque |
|---|---|---|
| M4 24 Go | 2 min 10 s | stable |
| M2 Pro 16 Go | 2 min 45 s | rebuild complet occasionnel (frontières de modules) |
| M3 Pro 18 Go | 2 min 22 s | stable |
Changer de version majeure Xcode ou SWIFT_VERSION invalide ModuleCache — une raison pour laquelle la CI ralentit en saison WWDC. En CI, faire survivre DerivedData entre jobs bat le M5 ; même M4 : disque éphémère P50 28 min, disque persistant P50 9 min (voir guide d’accélération).
6) 16 Go / 24 Go / 32 Go : comment choisir
| Configuration | Cas d’usage | Risques grands projets |
|---|---|---|
| 16 Go | runner CI CLI pur ; pas de simulateur ; un job | xcodebuild test + Archive en parallèle → swap ; indexation Xcode GUI saccadée |
| 24 Go | runner partagé + dépannage VNC occasionnel ; 10–30 builds/jour | Proj-β avec 2 simulateurs simultanés encore juste |
| 32 Go | monorepo, tests UI parallèles, Instruments permanent | coût plus élevé ; rendement décroissant pour le seul compile |
Avec la hausse des prix mémoire en 2026, 24 Go est le sweet spot pour le niveau L. Budget 16 Go : séparer tests UI et Archive sur des labels runner différents — voir séparation runners beta / production.
7) Parallélisme : faire tourner les 10 cœurs du M4
xcodebuild lit les cœurs disponibles par défaut, mais les grands projets sont souvent freinés par :
SWIFT_COMPILATION_MODE = wholemodulefait exploser la mémoire sur les gros targets — scinder par module coûte moins que plus de RAM.- Désactiver
DEBUG_INFORMATION_FORMAT = dwarf-with-dsyminutile en Release CI (garder en Debug local). -jobsexplicite : en datacenter nous utilisons souvent-jobs 8(2 cœurs pour système et sshd) pour éviter l’OOM.- CocoaPods
use_frameworks! :linkage => :staticréduit le temps de link dynamique, allonge le premier build — arbitrage d’équipe.
Si Activity Monitor ne montre que 4–5 processus swift-frontend à fond, c’est souvent des dépendances de targets sérialisées ou un fichier Swift géant — consultez Build Timeline (Xcode 16+) plutôt que d’accuser le M4.
8) Deux modèles de charge : poste de dev vs CI 7×24
Modèle A · compilation distante (voir adieu Xcode lent) : machine légère en local, SSH vers M4 pour xcodebuild. Priorité : latence incrémentale et VNC fluide — 24 Go plus confortables.
Modèle B · CI self-hosted : GitHub Actions / GitLab Runner sur M4, dizaines de runs par jour. Priorité : DerivedData persistante, durée de vie SSD, file d’attente. 16 Go suffisent souvent ; le goulot est la queue, pas la puce.
Cache Flutter multi-plateforme : Flutter iOS CI. Pipeline Fastlane / TestFlight : guide CI self-hosted.
9) Quand passer au M4 Pro, ajouter un runner ou scaler dans le cloud
Face à ces signaux, ajouter des machines bat ajouter des cœurs :
- Cold start P50 stable >18 min sans scission de modules à court terme — gouvernance XL plutôt que seulement une puce Pro.
- File PR sur le même runner >15 min — un second M4 16 Go en horizontal bat un M4 Pro seul.
- 3+ tests UI simulateur en parallèle — 32 Go ou machine de test dédiée ; labels compile et test séparés.
- Délais d’achat, électricité bureau, ops limités — M4 bare metal cloud à la journée ; TCO runners : comparatif six régions.
Le M4 Pro (CPU 12 cœurs minimum) n’était que ~8 % plus rapide à froid sur Proj-α pour un prix bien plus élevé — sans transcodage vidéo ni LLM local : pour iOS, prioriser le nombre de runners.
10) Questions fréquentes
Un Mac mini M4 16 Go peut-il compiler de grands projets iOS ? Oui, comme nœud CI dédié ; pas Xcode GUI + deux simulateurs en même temps. Pour le dev distant, 24 Go conseillés.
Combien plus rapide que macOS hébergé GitHub ? Segment xcodebuild seul souvent 10–20 % ; chaîne complète hébergée P50 25–45 min (file + cache froid), M4 self-hosted 8–12 min avec DerivedData persistante.
Vaut-il la peine d’attendre le Mac mini M5 ? Si le goulot est un disque CI éphémère ou du swap en 16 Go, le M5 n’aidera guère. Si le projet grossit de 30 %+ de fichiers par an, réévaluer à l’automne ; aujourd’hui M4 + runners persistants est pragmatique. Contexte : pourquoi le M5 était absent à WWDC 26.
Une VM macOS peut-elle remplacer le bare metal ? Signature, scheduling des cœurs performance, Metal/Simulateur sont instables en VM partagée. Pour une vraie pipeline, Mac mini bare metal — comparaison : VM vs matériel réel.
Le même M4—du café à Slack
Pass 48 h sur votre repo → Tarifs M4 · Guide runner : self-hosted