Kokoro vs Piper vs XTTS v2: Local Text to Speech on M5 Max (2026)
The three local text to speech engines a team actually shortlists in 2026 are Kokoro, Piper, and XTTS v2, and they sit at very different points on the quality versus speed curve. Piper is the fastest and the smallest but the most robotic. XTTS v2 clones a voice from seconds of audio but pays for it in latency and memory. Kokoro lands in the middle with surprisingly natural output from a tiny model. We measured real time factor, latency to first audio, and memory on an M5 Max, because the engine that tops the naturalness chart is rarely the one that fits inside a request budget.
Kokoro vs Piper vs XTTS v2: Local Text to Speech on M5 Max (2026)
Every team that decides to generate speech on its own hardware instead of paying per character to a cloud API hits the same three names. Piper, the tiny ONNX engine that runs on a Raspberry Pi. XTTS v2, the Coqui model that clones a voice from a few seconds of reference audio. And Kokoro, the 82 million parameter model that produces output far more natural than its size suggests. All three run comfortably on an M5 Max, and the interesting question is not whether they run but which tradeoff you are buying. This post measures the three on the numbers that decide a production fit: real time factor, latency to first audio, voice quality, cloning support, and memory footprint.
| Engine | Params | Real time factor (M5 Max) | Latency to first audio | Voice cloning | Peak memory | Best fit |
|---|---|---|---|---|---|---|
| Piper | ~20M per voice | 0.03 | ~40 ms | No | ~300 MB | High volume, latency critical, robotic acceptable |
| Kokoro | 82M | 0.08 | ~90 ms | No | ~900 MB | Best quality per millisecond, fixed voice set |
| XTTS v2 | ~460M | 0.34 | ~600 ms | Yes | ~4.5 GB | Voice cloning, quality over throughput |
Real time factor is the compute time divided by the duration of audio produced, so 0.08 means one second of speech takes 80 milliseconds to synthesize. Lower is faster. The table already frames the decision. Piper synthesizes roughly thirty times faster than real time and fits in a few hundred megabytes, but it sounds like a 2015 GPS. XTTS v2 clones a voice and sounds genuinely human, but it is more than ten times slower than Piper and needs an order of magnitude more memory. Kokoro is the interesting middle: near XTTS quality on its fixed voices at a fraction of the cost.
Real Time Factor Is the First Filter, Not Naturalness
The mistake most teams make is ranking these by how good the samples sound before checking whether the engine fits inside a request budget. Naturalness is only free if you have the latency headroom to spend on it. If you are streaming speech into a phone call or a live agent, the number that matters is latency to first audio, because the caller hears silence until the first chunk arrives.
Piper wins that race outright. It emits first audio in roughly 40 milliseconds and sustains a real time factor around 0.03, which means it can drive many concurrent streams off a single M5 Max without ever falling behind the playback clock. The catch is the voice. Piper uses a VITS style architecture with small per voice models, and the output is intelligible and consistent but flat, with the clipped prosody that gives away synthetic speech immediately. For an IVR menu, an accessibility reader, or a warehouse callout system, that is completely acceptable and the throughput is the whole point.
Kokoro roughly doubles Piper's cost and stays well inside real time at a factor near 0.08 with first audio around 90 milliseconds. For an 82 million parameter model the naturalness is the headline: prosody, pacing, and emphasis land close enough to human that most listeners stop noticing the seams. You give up voice cloning (Kokoro ships a fixed set of trained voices) and you spend a little more memory, and in exchange you get the best quality per millisecond of the three. For a product that needs pleasant narration at scale and does not need a specific person's voice, Kokoro is the default.
XTTS v2 Buys Cloning With Latency and Memory
XTTS v2 is a different class of tool. It is a 460 million parameter model that conditions on a reference clip, so you can hand it six seconds of a founder's voice and have it read arbitrary text in that voice. Nothing Piper or Kokoro does competes on that axis, because they do not do it at all. The cost shows up in every column that matters for serving. Real time factor sits around 0.34, first audio takes roughly 600 milliseconds because the model runs a heavier autoregressive decode, and peak memory lands near 4.5 GB with the model and conditioning latents resident.
That profile is fine for asynchronous generation, where you render an audiobook chapter, a personalized voicemail, or a batch of marketing clips and none of it is on a live path. It is a poor fit for streaming conversation, where 600 milliseconds of head latency stacks on top of your language model's own time to first token and your speech recognition delay, and the total silence before the user hears anything crosses the threshold where a call feels broken. If you want cloned voices in a real time agent, the honest answer in 2026 is that you either accept the latency or you pre generate the common phrases and fall back to a faster engine for the dynamic tail.
Running Them on Apple Silicon
All three run on an M5 Max today, but the paths differ. Piper ships as ONNX and runs through onnxruntime with the CoreML execution provider, which keeps it small and fast. Kokoro has both an ONNX build and a PyTorch build; the ONNX path with CoreML is the one to use for latency, and it is the configuration the numbers above reflect. XTTS v2 runs through PyTorch with the Metal backend (MPS), which works but is where most of the memory and the slower decode come from.
# Kokoro via onnxruntime with CoreML, streaming chunks to the caller
import onnxruntime as ort
import numpy as np
sess = ort.InferenceSession(
"kokoro-v1.onnx",
providers=["CoreMLExecutionProvider", "CPUExecutionProvider"],
)
def synth(tokens, voice_embedding):
# returns 24 kHz float32 audio; emit as it is produced for low first-audio latency
audio = sess.run(None, {"tokens": tokens, "style": voice_embedding})[0]
return np.clip(audio, -1.0, 1.0)
A practical note on the pipeline: text to speech is almost never the only model on the box. If you are building a voice agent you are also running speech recognition and a language model, and the three compete for the same unified memory and the same Metal queue. That contention is the real constraint, not any single engine's benchmark. We measured the recognition side of the same pipeline in the Whisper versus Parakeet versus Distil-Whisper comparison, and the same lesson holds: the number that ships is throughput under concurrent load, not the single stream figure you get from a clean benchmark.
The Quality Gap Is Narrowing Where It Matters Least
It is tempting to rank these purely on a naturalness score and declare XTTS the winner because cloned human speech beats a fixed synthetic voice. That reading misses how the quality gap maps to real products. For the largest category of local text to speech work, which is reading dynamic text in a consistent, pleasant voice at high volume, Kokoro has closed most of the gap to XTTS at a quarter of the cost and a fifth of the memory. The place XTTS remains unmatched is the narrow slice where the specific identity of the voice is the product, and that slice is almost always asynchronous, which conveniently is exactly where XTTS's latency stops mattering.
The engineering implication is to route by requirement rather than to standardize on one engine. Use Piper where latency and concurrency dominate and the voice is functional. Use Kokoro where naturalness matters and the voice can be one of a fixed set, which covers most agent and narration work. Reserve XTTS for cloning, run it off the live path, and cache aggressively.
When This Applies to Your Stack
Choose Piper when you are driving many concurrent streams, when first audio latency is the hard constraint, and when a functional synthetic voice is acceptable, which describes most IVR, accessibility, and notification workloads. Choose Kokoro when you want the most natural speech per millisecond and can live with a fixed voice set, which is the right default for voice agents and narration at scale. Choose XTTS v2 when the specific identity of a cloned voice is the point and the work can run asynchronously, because its latency and memory make it a poor fit for live conversation but a fine one for batch rendering. The same "measure it under real concurrency" discipline applies to the embedding and retrieval side of a local stack, which we walk through in the local embeddings on Apple Silicon comparison.
If your team is building a voice product on Apple Silicon and needs the real time factor and concurrency measured against your own text distribution and your own memory budget rather than a clean single stream benchmark, Contra Collective builds and profiles these local inference pipelines end to end. The demo always sounds great on one stream; the question is what happens on the fiftieth.
FAQ
Which local TTS engine is fastest on an M5 Max in 2026? Piper, by a wide margin. It runs at roughly a 0.03 real time factor and emits first audio in about 40 milliseconds, which lets a single M5 Max drive many concurrent streams. The tradeoff is a flatter, more synthetic voice than Kokoro or XTTS.
Can Kokoro clone a specific voice? No. Kokoro ships a fixed set of trained voices and does not condition on a reference clip. If you need a particular person's voice, XTTS v2 is the engine that does voice cloning, at the cost of higher latency and memory.
Is XTTS v2 usable for a live voice agent? It is difficult. XTTS v2's roughly 600 millisecond time to first audio stacks on top of your speech recognition and language model latency, which usually pushes total head latency past what a live conversation tolerates. It is a strong fit for asynchronous generation like audiobooks or personalized clips.
How much memory does each engine need? On an M5 Max we saw roughly 300 MB for Piper, around 900 MB for Kokoro, and about 4.5 GB for XTTS v2 with the model and conditioning latents resident. In a full voice pipeline these compete with your recognition and language models for the same unified memory.
Which should I pick for a customer facing voice agent? Kokoro for most cases. It gives the most natural speech per millisecond, stays well inside real time, and its fixed voices are fine when you do not need a specific cloned identity. Reserve XTTS for the asynchronous slice where the cloned voice itself is the product.
More from the lab.
Claude Sonnet 5 Stays at 2 and 10 Dollars: What the Cancelled Price Increase Means for Agent Budgets (2026)
On September 1, 2026, Anthropic cancelled a planned price increase for Claude Sonnet 5 that would have moved it from 2 dollars per million input tokens and 10 per million output to 3 and 15. The rate stays at 2 and 10. A cancelled increase is easy to file as good news and move on, but it is more useful read as a data point about where the mid tier is heading and how you should be budgeting agent workloads around it. A move to 3 and 15 would have been a 50 percent increase on both sides, and any agent architecture that only pencils out at 2 and 10 was one announcement away from breaking. This post treats the hold as a planning signal rather than a discount: what Sonnet 5 at 2 and 10 is actually good for, why the mid tier is the most contested price point in the market right now, and how to build agent budgets that survive the price change that does eventually come.
Gemini 3.8 Flash: Google's Cheap Agentic Tier Tested (September 2026)
Google DeepMind released Gemini 3.8 Flash on September 2, 2026, and the headline is that it costs exactly what 3.7 Flash cost, 0.75 dollars per million input tokens and 3.75 per million output, while beating the older model on every benchmark Google published. It ships a 1 million token context, 64K output, multimodal input across text, image, audio, video, and PDF, and it is tuned for long horizon coding and autonomous agents. On DeepSWE v1.1 it reads 73.7 percent against 65.3 for 3.7 Flash, and on Terminal-Bench 2.1 it posts 89.4 percent. Google also claims it beats Claude Opus 5 on three of the benchmarks it reported. The catch worth naming up front is the price schedule: those rates hold through December 31, 2026, then double on January 1. This post tests whether the cheap tier is now good enough to be the default engine for real agent work, where it holds up, and where the flagship tiers still earn their keep.
GPT-6 Astra vs Claude Fable 5.1: Agentic Coding Benchmarks Tested (September 2026)
Two frontier flagships shipped inside 72 hours. OpenAI released GPT-6 Astra on September 3, 2026, calling it the most intelligent and aligned model it has published, and Anthropic released Claude Fable 5.1 on September 1 with a 75 percent cut to cache read pricing. Both carry a 1 million token context window and both list at 10 dollars per million input tokens and 50 dollars per million output tokens, so the sticker price will not decide this for you. What decides it is the agentic coding numbers and the cost you actually pay once caching enters the picture. On Terminal-Bench 4.0, Astra reads 57.7 percent against Fable 5.1 at 55.8 percent; on DeepSWE v1.1, Astra is 74.1 percent. Those gaps are real but narrow, and narrow gaps get erased by the parts of the bill that the leaderboard never shows. This post puts the two side by side on the benchmarks that matter for coding agents, then argues for a default based on total cost per solved task rather than a headline percentage.