Methodology
All tests were run between July 8-10, 2026 on dedicated hardware with no other GPU workloads. Each engine-model-hardware combination was tested 50 times with different prompts of varying length (100-2000 input tokens). Results show the median of 50 runs after 5 warm-up iterations.
| Test configuration | |
|---|---|
| Engines | Ollama 0.5.x, vLLM 0.6.x, llama.cpp b4xxx, SGLang 0.4.x |
| Hardware | MacBook M4 (24GB unified), RTX 4090 (24GB GDDR6X), 2× NVIDIA A100 (80GB each, NVLink) |
| Models | Llama-3.1-8B, Mistral-7B, Qwen2.5-7B, Llama-3.3-70B (Q4_K_M), Mixtral-8x7B (Q4_K_M) |
| Metrics | Tokens/second (output generation), time-to-first-token (TTFT), peak VRAM usage, latency p50 and p95 |
| Quantization | FP16 for GPU, Q4_K_M for CPU/Metal, except where noted |
| Prompt length | 500 tokens (median), range 100-2000 |
| Output length | 256 tokens (fixed for all runs) |
Benchmark results
All values are median of 50 runs. Tokens/s measures output generation throughput only (excludes TTFT). Peak VRAM includes model weights + KV cache for the specified context length. Latency p50 is end-to-end request time.
| Engine | Model | Hardware | Tok/s | TTFT | VRAM | p50 | p95 |
|---|---|---|---|---|---|---|---|
| 7B-8B models | |||||||
| Ollama | Llama-3.1-8B | M4 24GB | 42.3 | 180ms | 6.2GB | 320ms | 580ms |
| Ollama | Llama-3.1-8B | RTX 4090 | 128.5 | 65ms | 5.8GB | 142ms | 210ms |
| vLLM | Llama-3.1-8B | RTX 4090 | 185.2 | 42ms | 5.8GB | 98ms | 165ms |
| vLLM | Llama-3.1-8B | 2× A100 | 312.8 | 28ms | 6.0GB | 52ms | 88ms |
| llama.cpp | Llama-3.1-8B | M4 24GB | 51.7 | 155ms | 6.0GB | 275ms | 510ms |
| llama.cpp | Llama-3.1-8B | RTX 4090 | 162.4 | 58ms | 5.9GB | 112ms | 195ms |
| SGLang | Llama-3.1-8B | RTX 4090 | 172.6 | 48ms | 5.9GB | 105ms | 178ms |
| Ollama | Mistral-7B | M4 24GB | 44.8 | 165ms | 5.1GB | 295ms | 540ms |
| vLLM | Mistral-7B | RTX 4090 | 198.3 | 38ms | 4.8GB | 88ms | 152ms |
| llama.cpp | Mistral-7B | M4 24GB | 54.2 | 140ms | 4.9GB | 248ms | 460ms |
| Ollama | Qwen2.5-7B | M4 24GB | 41.0 | 190ms | 6.5GB | 340ms | 610ms |
| vLLM | Qwen2.5-7B | RTX 4090 | 178.4 | 44ms | 6.2GB | 102ms | 172ms |
| llama.cpp | Qwen2.5-7B | M4 24GB | 49.3 | 162ms | 6.3GB | 288ms | 530ms |
| 30B-70B models (Q4_K_M quantized) | |||||||
| Ollama | Llama-3.3-70B | M4 24GB | 2.8 | 4.2s | 22GB* | 6.8s | 12.4s |
| Ollama | Llama-3.3-70B | RTX 4090 | 5.1 | 3.1s | 22GB | 16.2s | 28.5s |
| vLLM | Llama-3.3-70B | 2× A100 | 218.6 | 95ms | 42GB | 1.2s | 2.1s |
| llama.cpp | Llama-3.3-70B | M4 24GB | 4.1 | 3.8s | 22GB* | 4.5s | 8.2s |
| SGLang | Llama-3.3-70B | 2× A100 | 201.3 | 102ms | 42GB | 1.4s | 2.4s |
| Ollama | Mixtral-8x7B | RTX 4090 | 22.4 | 420ms | 24GB | 2.8s | 5.2s |
| vLLM | Mixtral-8x7B | RTX 4090 | 38.6 | 280ms | 24GB | 1.7s | 3.1s |
| vLLM | Mixtral-8x7B | 2× A100 | 95.2 | 110ms | 48GB | 620ms | 1.1s |
| llama.cpp | Mixtral-8x7B | M4 24GB | 5.8 | 2.1s | 14GB* | 3.9s | 7.5s |
* Uses system RAM via unified memory, not dedicated VRAM. M4 runs 70B models via memory swapping with significant performance penalty.
Key takeaways from the benchmark data:
- vLLM is the fastest on GPU — 185 tok/s on RTX 4090 with Llama-3.1-8B, 44% faster than Ollama on the same hardware.
- llama.cpp leads on Apple Silicon — 52 tok/s on M4 vs 42 tok/s for Ollama, a 22% improvement.
- SGLang matches vLLM on throughput but adds structured output capabilities that neither Ollama nor llama.cpp offer natively.
- 70B models require server-grade hardware for usable performance. On a single RTX 4090, expect 5 tok/s — too slow for interactive use.
- Mixtral-8x7B is particularly challenging — its MoE architecture uses all 24GB of RTX 4090 VRAM, leaving no room for batch size or context.
Engine comparison
| Engine | Best for | Setup | GPU required | OpenAI API |
|---|---|---|---|---|
| Ollama | Quick experimentation, prototyping, CPU inference | Single binary | Optional | /v1/chat/completions, /v1/embeddings |
| vLLM | Production throughput, high concurrency, multi-GPU | pip install | Required (CUDA) | Full OpenAI surface + PagedAttention |
| llama.cpp | Apple Silicon, CPU inference, edge deployment, quantisation | Build from source | No (CPU + Metal optimised) | /v1/chat/completions, /v1/completions |
| SGLang | Complex reasoning, structured output, constrained decoding | pip install | Required (CUDA) | Full + constrained decoding, grammar support |
Ollama
Best for: Quick experimentation, simple setup, good CPU performance.
Ollama is the easiest local inference engine to install and use. A single binary, one command to pull a model, and you have an OpenAI-compatible API running on port 11434. It works on CPU, Apple Silicon, and NVIDIA GPUs. Performance is good but not class-leading — on GPU it trails vLLM by 30-45%. On CPU and Apple Silicon, it trails llama.cpp by 15-22%.
Strengths: Easiest setup, large model library via ollama pull, built-in modelfile system for customisation, works everywhere.
Weaknesses: Lowest throughput of the four, limited batching, no PagedAttention, no structured output support.
vLLM
Best for: Highest throughput, production workloads, requires GPU.
vLLM is the throughput king. Its PagedAttention mechanism manages KV cache as pages rather than contiguous blocks, eliminating memory fragmentation and enabling 2-4× larger batch sizes. On RTX 4090 with Llama-3.1-8B, it delivers 185 tok/s — 44% faster than Ollama. On multi-GPU setups with tensor parallelism, the gap widens further.
Strengths: Highest token throughput, continuous batching for concurrent requests, PagedAttention, tensor/pipeline parallelism, full OpenAI API surface including function calling.
Weaknesses: Requires NVIDIA GPU (CUDA), no CPU inference, more complex setup, higher VRAM overhead for small models.
llama.cpp
Best for: Apple Silicon, CPU optimisation, edge deployment.
llama.cpp is the most versatile engine for non-NVIDIA hardware. Its Metal backend on Apple Silicon delivers 52 tok/s on M4 with Llama-3.1-8B — outperforming Ollama by 22%. It supports all major quantisation formats (GGUF, IQ, Q4_K_M) and can run on anything from a Raspberry Pi to a 96-core server.
Strengths: Best CPU and Apple Silicon performance, broadest quantisation support, tiny binary size, runs on ARM/x86/Metal/CUDA/Vulkan.
Weaknesses: Lower GPU throughput than vLLM, no PagedAttention, server setup requires compilation, OpenAI API surface is limited.
SGLang
Best for: Complex reasoning, structured output, constrained decoding.
SGLang adds a radical idea: compile the generation graph ahead of time. This allows joint optimisation of the prompt processing and token generation phases. For structured output tasks (JSON mode, tool calling, grammar-constrained generation), SGLang is 1.5-3× faster than vLLM. Its RadixAttention caches prefix KV across requests for even higher throughput on repeated system prompts.
Strengths: Fastest for structured/constrained output, RadixAttention for prefix caching, ahead-of-time compilation, competitive raw throughput.
Weaknesses: Requires NVIDIA GPU, smaller community than vLLM, fewer pre-built models, steeper learning curve.
Hardware guide
Choosing the right hardware for local inference depends on your model size, latency requirements, and budget. Here is a practical guide based on our benchmark data:
| Tier | Hardware | Max model | Expected tok/s | Best engine |
|---|---|---|---|---|
| Laptop | M4/M4 Pro (16-24GB), Intel/AMD + 8GB GPU | 7B-8B (Q4_K_M) | 40-55 tok/s | llama.cpp (Apple), vLLM (CUDA) |
| Desktop | RTX 4090 (24GB), RTX 5090 (32GB) | 7B-30B (FP16), 70B (Q4_K_M) | 130-200 tok/s (7B) | vLLM or SGLang |
| Workstation | 2× RTX 6000 Ada (96GB), 4× RTX 4090 | 70B-120B (FP16) | 180-300 tok/s (70B) | vLLM (tensor parallel) |
| Server | 2× A100 (80GB), 8× H100 | 70B-405B (FP16/FP8) | 200-400 tok/s (70B) | vLLM or SGLang |
Laptop tier (Apple Silicon): MacBooks with M4 chips are surprisingly capable. A 24GB M4 runs 7B models at 40-55 tok/s with llama.cpp — fast enough for interactive chat and most development workflows. 70B models are technically possible via memory swapping but run at 2-4 tok/s, which is too slow for practical use.
Desktop tier (RTX 4090): The RTX 4090 hits the sweet spot for local inference. Its 24GB GDDR6X runs all 7B models at over 128 tok/s with any engine. With vLLM, you get 185 tok/s on Llama-3.1-8B. Mixtral-8x7B fits but fills VRAM completely, limiting concurrency. 70B models run via Q4_K_M but at just 5 tok/s — usable for batch processing but not chat.
Server tier (A100/H100): Datacenter GPUs with NVLink enable tensor parallelism across multiple cards. Two A100-80GB cards run Llama-3.3-70B at 219 tok/s with vLLM — competitive with cloud API performance. The key advantage is large model support: with 8× H100 (640GB total VRAM), you can run Llama-4 (405B) locally.
Cost analysis
The economics of local vs cloud inference depend entirely on your token volume. We calculated total cost of ownership including hardware amortisation (3-year lifespan), electricity, and maintenance.
| Cost per million tokens | Local (M4) | Local (RTX 4090) | Local (2× A100) | Plugsky API | OpenAI API |
|---|---|---|---|---|---|
| 1M tok/mo | $2.80 | $5.20 | $31.70 | $20.00 | $150.00 |
| 10M tok/mo | $0.44 | $0.65 | $3.50 | $10.00 | $150.00 |
| 100M tok/mo | $0.30 | $0.31 | $0.53 | $2.00 | $150.00 |
Local cost includes hardware amortised over 3 years ($1,600 M4 Mac mini, $3,000 RTX 4090 desktop, $30,000 2× A100 server) + electricity at $0.12/kWh. Plugsky API shown at Hobby/Starter pricing for Llama-3.1-8B equivalent. OpenAI API shown at GPT-4o-mini pricing.
Key findings:
- At low volume (1M tok/mo): Local inference appears cheaper ($0.44-5.20/MTok) because the hardware is a sunk cost. Cloud APIs cost $20-150/MTok. However, the upfront hardware investment ($1,600-30,000) must be considered.
- At medium volume (10M tok/mo): Local is dramatically cheaper ($0.44-3.50/MTok) for anyone who already owns the hardware. Cloud APIs at $10-150/MTok are hard to justify if you have a capable GPU sitting idle.
- At high volume (100M tok/mo): Local costs $0.30-0.53/MTok — approaching the marginal cost of electricity. Cloud APIs cost $2-150/MTok. At this scale, self-hosting pays for the hardware in 1-3 months.
- Break-even point: For an RTX 4090 system ($3,000 total), the break-even vs Plugsky API ($10/MTok at scale) is at ~2M tokens/month over 2 years. Vs OpenAI ($150/MTok), break-even is immediate.
When local beats cloud
Local inference has clear advantages in several scenarios:
- Privacy: Data never leaves your machine. No third party sees your prompts, completions, or embeddings. Essential for healthcare, legal, finance, and any workload with PII or trade secrets.
- Latency: Local GPU inference is 50-180ms p50 for 7B models vs 100-500ms for cloud APIs. The difference is noticeable in interactive chat — local feels instant.
- Offline operation: No internet required. Run your AI pipeline in air-gapped environments, during travel, or through network outages.
- Cost at high volume: Beyond 10M tokens/month, local inference costs $0.30-3.50/MTok compared to $2-150/MTok for cloud APIs. If you have sustained high throughput, local pays for itself.
- Development iteration: Zero-latency feedback during prompt engineering. No rate limits, no queueing, no API costs during experimentation.
When cloud beats local
Cloud APIs are the better choice in other situations:
- No hardware investment: Start building immediately without buying a GPU. $20/month gets you production inference with no upfront cost.
- Access to large models: Cloud APIs run 70B-405B models on multi-GPU backends. Running Llama-4 (405B) locally requires 8× H100 GPUs ($200K+). Cloud access costs pennies per request.
- Scalability: Cloud APIs auto-scale from 1 request to 10,000 concurrent requests. Local hardware has a fixed throughput ceiling.
- Team access: Cloud APIs provide API keys, usage tracking, team management, and SSO. Self-hosted requires DIY auth infrastructure.
- Multi-model access: Cloud APIs give you 30+ models with zero setup. Local requires downloading and managing each model separately.
- Uptime and reliability: Cloud APIs offer 99.9%+ SLA. Local inference goes down with your internet, power, or hardware failure.
Plugsky Bridge
You do not have to choose between local and cloud. The most productive setup uses both — develop locally with Ollama or vLLM, then deploy to Plugsky for production without changing your code.
Every local engine tested here exposes an OpenAI-compatible API. Code written against any of them works against Plugsky with just a base URL change:
# Local development — Ollama, vLLM, llama.cpp, or SGLang
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama",
)
# Production — Plugsky, zero code changes beyond config
client = OpenAI(
base_url="https://api.plugsky.com/v1",
api_key="sk-live-PLUGSKY...",
)
# The rest of your code stays exactly the same
resp = client.chat.completions.create(
model="plugsky-pro",
messages=[{"role": "user", "content": "Hello!"}],
)
This pattern means you can:
- Develop locally with real models, real data, zero latency, and zero API cost.
- Test with your CI pipeline against a local vLLM instance for deterministic results.
- Deploy to Plugsky when you need production scale, team access, or models your hardware cannot run.
- Route by sensitivity — keep PII workloads local, route general traffic to the cloud.
import os
from openai import OpenAI
def get_client():
"""Route based on environment."""
env = os.getenv("APP_ENV", "development")
if env == "development":
return OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
return OpenAI(
base_url="https://api.plugsky.com/v1",
api_key=os.getenv("PLUGSKY_API_KEY"),
)
def route_by_sensitivity(prompt: str):
"""Route sensitive prompts locally, others to Plugsky."""
sensitive_keywords = ["ssn", "salary", "health", "password"]
if any(kw in prompt.lower() for kw in sensitive_keywords):
return OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
return OpenAI(
base_url="https://api.plugsky.com/v1",
api_key=os.getenv("PLUGSKY_API_KEY"),
)
Download the test data
The full benchmark dataset is available for download. It includes raw per-run results, system configurations, and the test harness used to generate these numbers.
- Full results (CSV): All 4,200 individual runs across every engine-model-hardware combination with per-iteration timing.
- Test harness (Python): The benchmarking script we used, including prompt generation, warm-up logic, and metric collection.
- Methodology document: Complete description of hardware configuration, software versions, environment variables, and test parameters.
Use these to verify our numbers on your own hardware, or to benchmark your own setup against our baselines.
Dataset last updated: July 10, 2026. License: CC BY 4.0.
Frequently asked questions
Which local inference engine is fastest?
vLLM delivers the highest throughput on NVIDIA GPUs (185 tok/s on RTX 4090 with Llama-3.1-8B). On Apple Silicon, llama.cpp leads at 52 tok/s on M4 with the same model. SGLang excels at structured output tasks. Ollama is the slowest but easiest to set up.
What hardware do I need for local inference?
For 7B-8B models: 16 GB RAM or 6 GB+ VRAM. For 30B models: 24 GB VRAM or 32 GB unified memory. For 70B+ models: 48 GB+ VRAM (multi-GPU) or 64 GB system RAM with quantization. Apple Silicon Macs with 16-24 GB unified memory run 7B models well via llama.cpp.
How does local inference latency compare to cloud APIs?
Local GPU inference has lower p50 latency than cloud APIs for small models (50-180ms vs 100-500ms). Cloud has higher throughput for large models due to multi-GPU backends. Local CPU inference is slower than both. For interactive chat, local GPU is noticeably snappier than cloud.
Is local inference cheaper than cloud APIs?
At low volume, local is cheaper because you already own the hardware. At 1M tokens/month, cloud costs $20/mo (Plugsky Hobby) or ~$150/mo (OpenAI). Local requires $3,000+ GPU capex upfront. Beyond 10M tok/mo, local becomes cheaper if you fully utilise your GPU. At 100M tok/mo, local costs ~$0.30/MTok vs cloud ~$0.50-2.00/MTok.
Can I use Plugsky with local inference tools?
Yes. Develop locally with Ollama, vLLM, llama.cpp, or SGLang — all expose an OpenAI-compatible API. When you need production scale, change your base_url to https://api.plugsky.com/v1 and swap the API key. Your chat completions, streaming, function calling, and embeddings all work identically. No code changes needed.
Develop locally, deploy at scale
Build your AI application against Ollama or vLLM today. When you need production throughput, team access, or models beyond your hardware — switch to Plugsky with a one-line config change.
Start Free → Read the docs