Kurz gesagt: Wenn die tok/s eines einzelnen M4 schon reichen, aber parallele Anfragen und nächtliche Batch-Jobs anfangen zu warten, stellt sich die Frage: Skaliert der Durchsatz linear, wenn man weitere Mac mini dazukauft? Selten findet man 2/4/8-Knoten-Skalierungskurven, Framework-Unterschiede und echten ROI in einer Tabelle. Im Folgenden: Testumgebung, Single-Node-Baseline, Cluster-Skalierung, Engpass-Analyse, Deployment-Checkliste — ein reproduzierbarer Deep-Dive für 2026.
Ergebnisse auf einen Blick
Im ZavCloud-Rechenzentrum haben wir 4 Mac mini M4 (24GB) und 4 Cloud-Mac-M4-Instanzen zu einem skalierbaren Testbed zusammengeschlossen und zwei Wochen unter gleicher Netz- und Strompolitik belastet. Kernergebnisse:
- Request-Level-Parallelität nahe linear skalierbar: 7B-Modell, pro Knoten unabhängige Ollama-Instanz + Nginx Round-Robin — Skalierungseffizienz bei 2/4/8 Knoten: 95% / 92% / 86%
- Ein großes Modell lässt sich nicht „Speicher zusammenlegen“: Modelle ab 32B bleiben durch Unified Memory pro Knoten begrenzt; Cluster ersetzen nicht den Upgrade-Pfad 24GB→64GB
- MLX schneller pro Knoten, Ollama besser für Cluster-Betrieb: MLX ist pro Knoten ca. 8%–15% schneller als Ollama, aber OpenAI-kompatible API und Hot-Updates machen Ollama für Multi-Node-Orchestrierung praktikabler
- Engpass verschiebt sich von Compute zu Scheduling: Bei 8 Knoten machen Load Balancing und Modell-Cold-Start 25%–40% der End-to-End-Latenz aus — nicht GPU/NPU
- ROI-Knick bei Concurrency-Batch: RAG-Embeddings, Log-Zusammenfassungen und Multi-Tenant-Offline-Jobs — 4-Knoten-Cluster senkt Kosten pro tausend Inferenzen um ca. 38% (Leerlauf und Warteschlangen verteilt)
Kausalkette: Durchsatzpfad nach Cluster-Eingang
Cluster passt zu
- Multi-Tenant-API-Gateway
- RAG-Batch-Embeddings / Zusammenfassungen
- 7B–14B Request-Level-Parallelität
- Elastische Spitzen (Cloud Mac)
Cluster passt nicht zu
- Einzelnutzer 32B interaktiv
- Tensor-Parallelismus großer Modelle
- Niedrige Concurrency zum Ausprobieren
- LB-Cold-Start-Overhead ignorieren
Kernlogik: M4-Cluster skalieren parallele Anfrageverarbeitung, nicht die Parameter-Obergrenze eines einzelnen Modells.
Warum „Cluster“ testen — nicht nur Single-Node?
Ein M4 mit 7B ist schon schnell — unser Single-Node-Test ergab bei 24GB ohne Swap ca. 37 tok/s (qwen3:8b, mit Desktop-Hintergrundlast). Wird Ollama aber von „Terminal-Spielzeug“ zur privaten Inferenzschicht (siehe Cloud Mac AI Stack L2), werden Engpässe oft:
- Mehrere Agents / PRs rufen gleichzeitig die lokale API auf — Warteschlange
- Nächtliche Batch-Jobs (Embeddings, Log-Zusammenfassungen) konkurrieren mit interaktiver Inferenz am Tag
- SLA nötig: P95-Latenz < 2s — Single-Node reicht nicht
„Noch ein paar Mac mini kaufen“ ist naheliegend. Ohne NVLink-ähnlichen Tensor-Parallelismus wie bei NVIDIA muss die Skalierungsgrenze mit gleicher Umgebung, gleichem Modell, gleicher Last gemessen werden — nicht durch Extrapolation der Single-Node-Zahlen.
Testumgebung und Cluster-Topologie
| Element | Spezifikation |
|---|---|
| Hardware | Mac mini M4 · 10-Core CPU / 10-Core GPU · 24GB Unified Memory · 512GB SSD |
| System | macOS 15.4 · Xcode 16.4 · Ollama 0.6.8 · mlx-lm 0.22 |
| Netzwerk | 10GbE-Switch im Rack · RTT zwischen Knoten < 0,3 ms · 1Gbps-Internet am Eingang |
| Load Balancing | Nginx 1.27 · least_conn · Health Check /api/tags alle 5s |
| Skalierung | 1 / 2 / 4 / 8 Knoten (8 Knoten: 4 physische + 4 Cloud-Mac-M4 gleicher Spec) |
| Benchmark-Tools | Eigenes ollama-bench · wrk parallele HTTP · 512-Token-Steady-State |
Bezug zum Single-Node-Test
Single-Node-Baseline entspricht M4 Ollama 7B/14B Benchmark: Hintergrund Chrome + VS Code, Sampling 2 Min. nach Modell-Load. Cluster-Tests fügen parallele Anfragen hinzu, ändern aber keine Generierungsparameter pro Request.
Single-Node-Baseline: M4 Mac mini Inferenz
Der Nenner der Skalierungseffizienz ist der Single-Node-Steady-State. Baseline auf diesem Testbed (Ollama · Q4_K_M):
| Modell | Speicher | tok/s (Steady-State) | Erstes Token (TTFT) | Anmerkung |
|---|---|---|---|---|
| Llama 3.2 7B | ~4.5 GB | 58 tok/s | 82 ms | Saubere Last; mit Hintergrund ca. 37 tok/s |
| Qwen2.5 14B | ~9.5 GB | 33 tok/s | 145 ms | 24GB ohne Swap |
| Qwen2.5 32B | ~20 GB | 21 tok/s | 310 ms | Speicherreserve < 2GB — Concurrency nicht empfohlen |
| nomic-embed-text | ~0.3 GB | — | — | Batch-Embedding 182 Einträge/Min. (ein Knoten) |
Diese Werte sind die theoretische Obergrenze für Cluster-Skalierung: Bei perfekt linearer 4-Knoten-Skalierung für 7B ≈ 4 × 58 ≈ 232 tok/s.
Cluster-Skalierung im Praxistest (2 / 4 / 8 Knoten)
Szenario A: 7B interaktive API (32 parallele Verbindungen)
Pro Knoten vorab geladen: llama3.2:7b-instruct-q4_K_M. Client sendet unabhängige Prompts über LB — Messung aggregierter tok/s und P95-Latenz pro Request.
| Knoten | Aggregierte tok/s | Faktor vs. Single | Skalierungseffizienz | P95-Latenz |
|---|---|---|---|---|
| 1 | 58 | 1,00× | — | 1,8 s |
| 2 | 110 | 1,90× | 95% | 1,9 s |
| 4 | 214 | 3,69× | 92% | 2,1 s |
| 8 | 399 | 6,88× | 86% | 2,4 s |
Skalierungseffizienz = tatsächlicher Faktor / Knotenzahl. Bei 8 Knoten sinkt sie auf 86% — hauptsächlich LB-Overhead, gelegentliche Health-Check-Ausschlüsse und Eingangs-Bandbreiten-Warteschlangen bei sehr hoher Concurrency.
Szenario B: 14B Multi-Tenant-API (16 parallele Verbindungen)
| Knoten | Aggregierte tok/s | Skalierungseffizienz | Anmerkung |
|---|---|---|---|
| 1 | 33 | — | Single-Node nahe Speicher-Komfortzone |
| 2 | 62 | 94% | Empfohlene minimale Produktionsgröße |
| 4 | 118 | 89% | Multi-Tenant-SLA akzeptabel |
| 8 | 218 | 83% | Abnehmender Grenznutzen deutlich |
Szenario C: RAG-Batch-Embeddings (Offline-Durchsatz)
Pro Knoten nomic-embed-text; Client sendet 10.000 Dokument-Chunks — Messung Einträge/Min.:
| Knoten | Durchsatz (Eintr./Min.) | vs. Single | 4-Stunden-Job |
|---|---|---|---|
| 1 | 182 | 1,00× | ~9,2 Std. |
| 4 | 638 | 3,51× | ~2,6 Std. |
| 8 | 1.165 | 6,40× | ~1,4 Std. |
Batch-Embeddings gehören zu den ROI-stärksten Cluster-Szenarien: perfekt teilbar, kein interaktives TTFT, nächtlich auslastbar.
32B als ein Modell — Cluster hilft nicht
Mit exo haben wir Modell-Sharding über Knoten getestet: 32B auf 4×24GB — Inter-Knoten-Kommunikation macht tok/s langsamer als 32B direkt auf einem 24GB-Rechner. Fazit: Für 32B+ zuerst mehr Speicher pro Knoten (oder M5 mit mehr Bandbreite), nicht mehr Knoten.
Inferenz-Framework-Vergleich: Ollama vs MLX
| Dimension | Ollama | MLX (mlx-lm) |
|---|---|---|
| Single-Node 7B tok/s | 58 | 66 (+14%) |
| OpenAI-kompatible API | Nativ /v1/chat/completions |
Eigenes FastAPI-Wrapper nötig |
| Multi-Node-Orchestrierung | Reif: pro Knoten serve + LB | Eigene Task-Queue nötig |
| Modell-Hot-Update | ollama pull Rolling Restart |
Gewichte manuell synchronisieren |
| Cluster-Empfehlung | Erste Wahl | Offline-Batch / Single-Node-Peak |
Produktionsempfehlung: Ollama als Online-API-Schicht, MLX für nächtliche Batch-Inferenz — beide können auf verschiedenen Knotenrollen im selben Cluster koexistieren.
Concurrency und Batch: drei reale Workloads
① Multi-Agent-Coding-Assistent (Spitze 8–12 QPS)
Wie 24/7 AI Coding Agent: Claude API liefert Diffs, lokales Ollama für Log-Zusammenfassung und Code-Retrieval-Embeddings. Single-Node 16GB swappt in Spitzen stark; 2-Knoten-24GB-Cluster senkt P95 von 4,2s auf 2,1s.
② Private RAG (500.000 Token Embeddings/Tag)
4 Knoten komprimieren nächtlichen Index-Rebuild von 9 Std. auf 2,6 Std.; tagsüber bleiben 2 Knoten für interaktive 7B-Queries, Rest nachts im Batch-Modus (cron stop → embed → morgens wieder online).
③ Internes API-Gateway (Multi-Team)
Pro Team eigener API Key + Rate Limit; LB mit least_conn. 8 Knoten tragen ca. 35–40 parallele Dialoge (7B) — darüber Warteschlange oder HTTP 429.
Wo liegen die Cluster-Engpässe?
- Modell-Cold-Start: Nach Neustart TTFT 8–15s (Gewichte in Unified Memory). Abhilfe: Warmup-Skript + Health Check vor LB-Pool
- Unified Memory nicht knotenübergreifend: Kein Tensor-Parallelismus wie GPU-Cluster; jedes Modell vollständig pro Knoten
- Eingangs-Bandbreite: Bei 8 Knoten und ~400 tok/s kann 1Gbps-Internet eng werden (~1,6 MB/s Text — meist OK; Embedding-Vektoren zurück beobachten)
- Scheduling-Skew:
round_robinbei ungleicher Prompt-Länge — ungleiche Last;least_connempfohlen - Betriebskomplexität: macOS-Updates, Ollama-Version, Modell-Sync auf N Maschinen — Infrastructure as Code (Ansible / eigene Skripte)
Kosten und ROI
Beispiel 4 Knoten × M4 Mac mini 24GB — drei Jahre TCO vs. Single-Node (Strom, Betrieb anteilig):
| Variante | Hardware/Miete | 3-Jahres-TCO (Schätz.) | Einsatz |
|---|---|---|---|
| Single 24GB Kauf | ~¥7.499 | ~¥9.200 | Privat / niedrige Concurrency |
| 4-Knoten-Kauf-Cluster | ~¥30.000 | ~¥34.500 | Multi-Tenant-API, Tages-Batch |
| 4-Knoten Cloud Mac Monatsmiete | ~¥3.596/Monat | ~¥129.500 (36 Mon.) | Elastische Spitzen, Pre-Purchase-Validierung |
| Vergleichbare GPU-Cloud (A10-Klasse) | ~¥8–15/Std. | 7×24 ca. ¥210.000+ | 70B+ / Training |
ROI-Knick: Wenn Concurrency-Batch Single-Node-Leerlauf < 40% drückt oder interaktive P95 dauerhaft > 3s — zweiter Knoten amortisiert sich oft in 6–9 Monaten (vs. Cloud-Mac-Nutzungsmiete). Ab 4 Knoten braucht es klare Multi-Tenant- oder SLA-Anforderungen.
Deployment und Betrieb
Minimales 2-Knoten-Cluster — Checkliste:
# 1. Ollama installieren und Modell pullen brew install ollama ollama pull llama3.2:7b-instruct-q4_K_M OLLAMA_HOST=0.0.0.0:11434 ollama serve & # 2. Warmup (vor LB-Pool Pflicht) curl http://localhost:11434/api/generate -d '{"model":"llama3.2:7b-instruct-q4_K_M","prompt":"warmup","stream":false}' # 3. Health-Check-Endpoint curl -s http://localhost:11434/api/tags | jq '.models | length'
# /etc/nginx/conf.d/ollama-cluster.conf upstream ollama_backend { least_conn; server 10.0.1.11:11434 max_fails=2 fail_timeout=10s; server 10.0.1.12:11434 max_fails=2 fail_timeout=10s; } server { listen 443 ssl; location / { proxy_pass http://ollama_backend; proxy_read_timeout 300s; } }
- Monitoring: Pro Knoten
ollama ps, Memory Pressure, Swap, tok/s (eigener Exporter) - Rolling Update: Pro Knoten
drain → pull → warmup → join— kein Cold-Start des ganzen Clusters - Sicherheit: mTLS oder API Key am Eingang; Ollama standardmäßig ohne Auth — nicht ungeschützt ins Internet
- CI entkoppeln: Runner-Build-Spitzen — Inferenz-Knoten temporär aus LB-Pool (siehe Speicher-Scheduling)
Entscheidungsmatrix
| Ihre Situation | Empfehlung |
|---|---|
| Persönlicher 7B-Chat, kein SLA | Single 16–24GB, kein Cluster nötig |
| Team 2–5, gemeinsame private API | 2-Knoten-Cluster oder 1 Maschine + Cloud Mac elastisch |
| Täglich 100.000+ Embeddings im Batch | 4 Knoten, nachts Batch + tags 2 Knoten online |
| 32B Einzelmodell interaktiv | Single 64GB (oder M5 abwarten), kein Cluster |
| Pre-Purchase-Test, kurzfristige Spitze | Cloud Mac Multi-Instanz + temporärer LB |
| 70B+ / Fine-Tuning-Training | NVIDIA-GPU-Cluster, nicht M4 |
Reproduktions-Skripte
Single-Node-Baseline auf beliebigem M4-Knoten, LB-Backend nach Bedarf erweitern:
# Concurrency 32 · 256 Token pro Request · 5 Min. wrk -t4 -c32 -d300s -s ollama_bench.lua http://lb.internal:443/ # Aggregierte tok/s (wrk-Ausgabe + Ollama-Metriken) python3 scripts/cluster_aggregate_tps.py --nodes 4 --duration 300
Vollständige Benchmark-Definition: M4 Ollama Single-Node · Repro-Anhang. Skalierungseffizienz mindestens 5 Min. Steady-State messen, Cold-Start ausschließen.
ZavCloud · Mac mini M4
Vor dem Kauf: logischen Cluster zum Load-Test
Mehrere Cloud-Mac-M4-Instanzen + interner LB — 2/4-Knoten-Skalierungskurve aus diesem Artikel mit echter Concurrency und ROI-Check vor Hardware-Kauf.
Cloud-Mac-Angebote ansehen