New: VidClean learns how you cut from one video you already finished, then drafts matching cuts on your next one. Try it free in the editor, and send bug reports or feature requests to hello@vidclean.net

Blog

Parakeet vs Whisper on CPU: 1,231 Production Jobs

By Melvin Bucio 12 min read

This is a sizing post for people running speech recognition on CPUs. If you are choosing between NVIDIA's Parakeet-TDT and faster-whisper for a self-hosted deployment, or trying to work out how many concurrent slots a box will support, the numbers below come from 1,231 real jobs rather than a benchmark harness.

Both engines run in production on the same container, routed by detected language, so this is close to a controlled comparison: same CPU, same queue, same audio pipeline, same week. What it is not is an accuracy comparison. This post is entirely about time.

Three results, in descending order of how much they will change your capacity plan. Whisper is about 1.6 times slower than Parakeet on files long enough for that to be the thing you are measuring. Whisper's speed varies twelvefold depending on the language, while Parakeet's varies less than twofold. And on short files, which are most files, neither of those numbers matters, because a fixed per-job overhead that has nothing to do with either model is the entire cost.

THE SHORT VERSION

Measured on 1,231 production jobs, August 1 to 20, 2026
  • Parakeet-TDT 0.6B v3 runs at a median 0.099 seconds of compute per second of audio on files over two minutes (n=677). faster-whisper small runs at 0.160 (n=111). About 10x and 6x faster than realtime respectively.
  • Whisper's median varies 12x across languages and Parakeet's varies 1.7x, on the same hardware, controlling for file length. Whisper's slowest language median is Hindi at 0.736; its fastest is Japanese at 0.061.
  • Fixed overhead is the whole story below about two minutes. On files under a minute, Parakeet's median real-time factor is 0.255 and Whisper's is 1.253, meaning Whisper takes longer than the clip lasts.
  • That overhead is not a constant, it is a distribution with a very long tail. On files of 30 seconds or less, processing takes a median 4.5 seconds, a p90 of 66.2 seconds and a p99 of 145.6 seconds.
  • The linear model fits well inside a week and badly across three. Parakeet's slope moves between 0.0822 and 0.1317 seconds per second week to week on unchanged code.
  • 8.4% of all jobs exceed 1.0x realtime, and 76 of those 104 jobs are under a minute of audio. The worst ratio in the sample is 14.230x, on a six-second file.

Hardware: one shared container, 2 vCPU budget, running up to two jobs concurrently. Parakeet is the int8 ONNX export with the memory arena disabled; Whisper is faster-whisper small at int8. Real-time factor here is always seconds of processing per second of audio, so lower is faster. See methodology.

FIELD GUIDE: WHAT "3X REALTIME" MEANS

Before any numbers, a disambiguation, because this one genuinely costs people money.

"3x realtime" is used in this field to mean two opposite things, and which one is meant is almost never stated.

The same phrase, two opposite readings
Convention "3x realtime" means One hour of audio takes
Speed multiple (fast)Three times faster than realtime20 minutes
Cost multiple (slow)Three times as long as realtime3 hours

A ninefold difference in capacity from the same four characters.

Our own codebase managed to hold both conventions at once. One subsystem's comments described GPU denoising as "25 to 35x realtime," meaning fast. Two constants in the transcription config described Whisper as running at "~3x realtime" and "~2.3x realtime," meaning slow. Both were accurate about their own subject and neither said which convention it used.

That ambiguity had a consequence. A feature's daily capacity was sized by reading the transcription constants as the cost of a transcription. They describe Whisper's worst case, and Whisper serves under a fifth of traffic. The cap was set at 5 jobs a day when the hardware supported roughly 80.

The fix is to never publish a bare multiplier. State seconds of processing per second of media, which is unambiguous because it has units, and which for a faster-than-realtime system is a number below 1. That is the convention used everywhere below, and it is what "real-time factor" or RTF conventionally means, though the term is not safe either: some tools report its reciprocal and still call it RTF. Say the units.

HEAD TO HEAD, CONTROLLING FOR LENGTH

The naive comparison is misleading. Across all 1,231 jobs, Parakeet's median real-time factor is 0.141 and Whisper's is 0.296, which looks like a 2.1x gap. But the two engines get different work: Whisper is the fallback for languages Parakeet does not cover, plus the language detector, and it receives a larger share of very short files, where fixed overhead inflates the ratio for reasons that have nothing to do with the model.

Restricting to files over two minutes, where per-job overhead is under a fifth of runtime, gives the honest comparison.

Real-time factor by audio length, seconds of compute per second of audio
Audio length Parakeet n Parakeet median Whisper n Whisper median
under 1 min2370.255701.254
1 to 5 min2540.132610.221
5 to 15 min1750.076300.166
15 to 30 min1290.075150.155
30 to 60 min1460.110260.172
over 60 min740.109140.071
over 2 min (all)6770.0991110.160

Medians. Lower is faster. Whisper's "over 60 min" cell rests on 14 jobs and its 15 to 30 cell on 15; treat both as indicative. The bolded row is the comparison worth quoting.

Parakeet's advantage on files long enough to measure is 1.6x, not the 2.1x the raw medians suggest. It is a real and useful advantage, and it is smaller than the headline arithmetic implies. If you are switching engines for throughput, budget for 1.6x and be pleased if you do better.

Two other things in this table are worth pausing on. Parakeet's median rises again above 30 minutes, from 0.075 to about 0.110, so the relationship is not cleanly linear at the long end. And Whisper's p90 across the same over-two-minute set is 0.804 against Parakeet's 0.199: the medians differ by 1.6x, but the ninetieth percentiles differ by 4x. Whisper is not just slower, it is far less predictable, which matters more than the median if you are sizing a queue against a timeout.

WHISPER'S SPEED DEPENDS ON THE LANGUAGE. PARAKEET'S DOES NOT.

This is the finding I would not have predicted, and it is the one most likely to break a capacity plan built on a single average.

Splitting the same over-two-minute jobs by detected language, Whisper's median real-time factor ranges from 0.061 to 0.736. That is a twelvefold spread on identical hardware, driven by nothing but which language is being decoded.

Median real-time factor by language, files over two minutes
Engine Language Jobs Median RTF
whisperHindi100.736
whisperUrdu40.277
whisperArabic140.185
whisperMalay90.138
whisperChinese210.133
whisperTagalog100.115
whisperIndonesian50.105
whisperJapanese90.061
parakeetFrench140.118
parakeetEnglish4470.108
parakeetItalian90.106
parakeetSpanish1000.095
parakeetLithuanian140.081
parakeetPortuguese400.081
parakeetRussian290.069
parakeetGerman90.068

Languages with at least 4 jobs (Whisper) or 8 jobs (Parakeet) over two minutes of audio. Whisper spread 12.0x, Parakeet spread 1.7x. Cells in the 4 to 10 job range are indicative; the direction and the size of the gap between engines are the robust part.

The mechanism is not mysterious. Whisper is an autoregressive encoder-decoder: it generates output tokens one at a time, so its decode cost scales with how many tokens the text turns into. Languages whose scripts tokenize poorly in Whisper's vocabulary produce far more tokens per second of speech and cost proportionally more. Parakeet-TDT is a transducer with a token-and-duration prediction head that emits over a fixed frame grid, so its cost tracks audio length rather than output length, and the language barely moves it.

The practical consequence: if you serve multilingual traffic on Whisper, your capacity depends on your language mix, and a shift in that mix will change your throughput without any code change. Sizing from an English-only benchmark, which is what almost every published Whisper benchmark is, will overstate your capacity for Indic-language traffic by roughly an order of magnitude. On Parakeet you can size from one number.

One correction to something we published earlier. An internal note recorded Whisper's worst case as 3.22x realtime on Burmese and attributed the spread to language. The spread by language is real and is the table above. But the extreme tail is not a language effect at all, as the next section shows.

ON SHORT FILES, NEITHER MODEL IS THE COST

Every job pays a fixed cost before a model sees anything: fetch the file from object storage, run ffmpeg to extract 16kHz mono audio, and for Whisper-routed jobs, run language detection first. None of that scales with audio length. All of it dominates on a short clip.

The worst real-time factors in the entire sample are all tiny files. The single worst is 14.230, which is 85.4 seconds of processing for a six-second clip. 104 jobs, 8.4% of the sample, exceeded 1.0x realtime, and 76 of those had under a minute of audio. Whisper's much-quoted 3.22x tail sits in this population and is an overhead artifact, not a decoding cost.

4.5s / 66.2s

median and p90 processing time for files of 30 seconds or less

n=217 jobs. p99 is 145.6 seconds. 19.4% of these jobs took over 30 seconds.

That gap is the important part. The overhead is not a constant to add to your model. It is a distribution whose p90 is roughly fifteen times its median, and whose p99 is over thirty times its median. Something takes 4.5 seconds most of the time and two minutes occasionally.

The cause is not model cold-start. Slow short jobs are, if anything, less likely to occur just after a deploy than fast ones, which rules out warm-up. It is the download: fetch time scales with file size, and audio duration does not predict file size. A six-second 4K clip is a large file containing almost no audio. Any model comparison run on local files will miss this cost entirely, and in a hosted deployment it is the largest single term for most jobs.

The two engines' own fixed costs also differ, and by more than you might expect. On files of 12 seconds or less, Parakeet's median total processing time is 3.0 seconds and Whisper's is 15.2 seconds. Most of that difference is the language-detection pass Whisper-routed jobs run before decoding. If your workload is dominated by short clips, that fixed difference is a bigger lever than any throughput ratio in this post.

THE LINEAR MODEL, AND ITS SHELF LIFE

We previously derived a planning model from a subset of this data, measured over August 8 to 14:

processing = 20 + 0.13 x duration

seconds, Parakeet, as published from the August 8 to 14 window

Re-fitting that same window from the fuller extraction reproduces it almost exactly: 20.5 + 0.1317 x duration, R-squared 0.863, n=405. That is a good check on the method, since it was derived independently.

It is also a good demonstration of why one week is not enough.

The same fit, three consecutive weeks, unchanged engine code
Window n Fit Median RTF over 10 min Slot shared
Aug 1 to 71971.1 + 0.1276 x d0.0800.0%
Aug 8 to 1440520.5 + 0.1317 x d0.15320.1%
Aug 15 to 204131.3 + 0.0821 x d0.06212.6%

Parakeet only, ordinary least squares. "Slot shared" is the share of jobs over five minutes that spent most of their runtime alongside a second job on the worker's other slot.

The slope moves by 1.6x and the median cost on long files by 2.5x, across three weeks, on the same engine code and the same container. The week we happened to publish from was the slowest of the three.

Contention explains part of it. Splitting Parakeet jobs over five minutes by whether they shared the worker with a second job: those that ran alone have a median of 0.077, those that spent most of their runtime alongside another job, 0.109 to 0.121. That is roughly a 1.4x penalty, and the slow week was the week with the most sharing. It does not explain all of it, and the remainder is most plausibly the noisy-neighbour behaviour of a shared cloud container, which is exactly the thing a benchmark on your own hardware will not reproduce.

Because ordinary least squares on a heavy-tailed length distribution is dominated by the longest files, a robust fit is a better central estimate. Theil-Sen over all 1,015 Parakeet jobs gives 3.3 + 0.0801 x duration, with the intercept near the 3.0-second median overhead measured directly rather than the 20 seconds OLS infers by averaging a bimodal tail into the constant.

If you need numbers to size with
  • Plan Parakeet at 0.10 seconds per second of audio, plus about 5 seconds per job.
  • Budget Parakeet at 0.20, its p90 above two minutes, plus 70 seconds per job for the download tail.
  • Plan Whisper at 0.16 and budget at 0.80, and only if your language mix resembles ours. If it includes Indic languages, measure your own.
  • Do not size a queue from a mean. The p90-to-median ratio is 2x on Parakeet, 5x on Whisper, and 15x on the fixed overhead.
  • Re-measure quarterly. Nothing in our code changed across a 2.5x swing in observed cost.

WHAT WE RUN, AND WHAT IT TOOK TO FIT

The timings above come from a specific deployment, and two details of it matter enough to reproduce here, because they are the difference between these numbers and an out-of-memory loop.

The ONNX Runtime memory arena has to be off. With the default arena enabled, steady-state resident memory grows by roughly 520MB over a session and eventually exceeds a 2GB container. It is one session option:

import onnxruntime as rt
import onnx_asr

so = rt.SessionOptions()
so.intra_op_num_threads = 2      # matches the 2-vCPU allocation
so.inter_op_num_threads = 1
so.enable_cpu_mem_arena = False  # arena on costs ~520MB RSS

model = onnx_asr.load_model(
    "nemo-parakeet-tdt-0.6b-v3",
    quantization="int8",
    sess_options=so,
    providers=["CPUExecutionProvider"],
)

Long files are decoded in windows, never loaded whole. Parakeet's ONNX export rejects inputs past roughly 200 seconds, a limit of its relative positional attention tables, and inference buffers scale with window length regardless: a 60-second window peaks near 1.65GB and a 30-second window near 1.16GB. Measured against an 1,800MB budget, 30-second windows peaked at 1,804MB, four megabytes over. We use 20-second windows with 5 seconds of overlap on each edge, and ffmpeg cuts them before inference so only one window is ever resident. That is what makes a 90-minute file possible in a 2GB container, not headroom.

Those 20-second windows are also what makes the join in this post's methodology verifiable, since the window count each job logs has to match its duration divided by 20.

Why route at all, rather than run one engine. Throughput is not the reason we moved the bulk of traffic to Parakeet. Whisper hallucinates on silence and low-signal audio, emitting phrases like "thank you for watching" into pauses, which for a general-purpose tool is worse than returning nothing. Parakeet's token-and-duration transducer returns nothing on silent segments, and a post-processing step that had existed only to strip Whisper's inventions was deleted outright. Whisper stays in the system as the language detector, the fallback for languages Parakeet does not cover, and a kill switch.

That detector runs a Whisper pre-pass over the first 30 seconds of any auto-language job, including the ones that then decode on Parakeet, so it is already inside every Parakeet timing in this post. It adds a second or two. It is not the reason Whisper-routed short jobs cost 15.2 seconds against Parakeet's 3.0; that gap is Whisper's own decode.

One capability follows the engine rather than the language. Word-level timestamps are produced only on the Parakeet path, because the Whisper adapter returns empty word boundaries, so anything built on word positions works for Parakeet-routed traffic and degrades for the rest.

On accuracy, which this post does not measure: informally, the two are close on clean native-accent English, Parakeet is better on accented English and clearly better on Spanish and Portuguese, which tracks its multilingual training set against Whisper small's predominantly English one. That is an impression from side-by-side comparison, not a word-error-rate study, and it should be treated as one.

METHODOLOGY

These are production jobs, not a benchmark suite. Nobody chose the files, the languages or the arrival times, which is the point and also the main limitation: there is no matched pair anywhere in this dataset. No single audio file was transcribed by both engines, so every comparison here is between distributions, not between runs.

The records were reconstructed from the transcription worker's own logs between August 1 and 20, 2026. The worker emits a job-start line carrying an internal queue identifier and the job identifier as its argument, a routing line naming the engine and the detected language, a line stating the audio duration and the number of decode windows, a completion line, and a finish line carrying elapsed seconds against the queue identifier. Three separate joins have to agree before a row is kept.

First, the queue identifier is mapped to the job identifier from the start line's argument, because the two are different values and pairing them by position is wrong. Second, the duration line is matched to the completion line that immediately follows it, and that completion line has to republish the same detected language and the same segment count. Third, and this is the check that makes the rest trustworthy, the window count in the duration line must equal the audio duration divided by that engine's window size, rounded up: 20 seconds for Parakeet, whose ONNX export rejects longer inputs, and 150 seconds for Whisper. The worker runs two jobs concurrently, so log lines from different jobs interleave; a mis-pairing produces a window count that fails this arithmetic. Of 1,256 candidate pairs, zero failed it: 19 were dropped for a missing engine or elapsed time and 6 for a zero duration, leaving 1,231.

Processing time is the worker's own elapsed time for the job: object-storage download, audio extraction, language detection where it runs, decoding, and artifact upload. It is end-to-end cost per job, which is the number a capacity plan needs, and it is not a model inference benchmark. Audio duration is logged to one decimal place in minutes, a 6-second granularity, which is why sub-minute real-time factors are coarse and why the length buckets rather than individual short rows carry the argument.

Concurrency was reconstructed by intersecting each job's inferred run interval with every other job's. A job is counted as slot-shared when more than half its runtime overlapped another job. That is an inference from timestamps, not a recorded fact, and it is the softest measurement in this post.

The sample includes transcriptions run as a stage of other tools: 968 plain transcriptions, 188 feeding the clip generator and 74 producing burned-in subtitles. All three do the same transcription work and end at the same point, so they are pooled. Style-profile extractions and the anonymous preview path log through different lines and are absent. That makes this population different from the one in the companion usage study, which counts only plain transcriptions; the two job counts are not meant to match.

Hardware: a single shared container with a 2 vCPU budget running up to two jobs at a time, alongside other services. Parakeet is nemo-parakeet-tdt-0.6b-v3, int8 ONNX, memory arena disabled, 20-second windows with 5-second overlap. Whisper is faster-whisper small at int8, 150-second windows, greedy decoding with beam size 1, Silero VAD on, and conditioning on previous text off. Absolute numbers are specific to that box. The ratios between engines, between languages and between length buckets are the transferable part.

Every figure was regenerated from a fresh log extraction immediately before publication by a script that re-runs the join, re-derives each statistic and then greps this page for all of them. The full per-job dataset is available as a CSV file, one row per job, with no identifiers.

This data is licensed CC BY 4.0. Feel free to reuse the numbers with credit to VidClean.

LIMITATIONS

No matched pairs, as above. The engines are selected by language, so the comparison is confounded with language by construction. The length-controlled table narrows this and the per-language table exposes it, but nothing here fully removes it. The cleanest statement the data supports is: on this traffic, on this box, Parakeet cost 1.6x less per second of audio.

Nothing about accuracy. Parakeet being faster is not an argument that it is better, and the routing exists because Parakeet covers a limited language set. Anyone choosing between them needs a word-error-rate comparison this post does not provide.

Whisper's cells are thin. 217 jobs total, and the per-language rows run from 4 to 21 jobs. The twelvefold spread is large enough to survive that thinness and the mechanism explains it, but the individual numbers will move with more data.

Parakeet's median rising above 30 minutes, from 0.075 to 0.110, is unexplained. Long jobs overlap other jobs more by definition, so contention is the obvious suspect, but this analysis does not separate that from a real per-length effect.

Concurrency is inferred, not recorded. The overlap figures rest on reconstructed intervals and on the assumption that elapsed time brackets the run cleanly.

And it is 20 days. Given that the three weeks inside it disagree by 2.5x, the correct reading of every absolute number here is "this is what it cost in August 2026," and the correct action for anyone sizing real capacity is to run the same measurement on their own hardware.

IF YOU JUST WANT A TRANSCRIPT

Most people reading a post like this are sizing a deployment. If you are not, and you simply want text out of a file, you can transcribe a video or audio file here, free in the browser, with no account needed. It is the same pipeline these measurements came from, engine routing and all.

VidClean is a solo project. Questions about the data or the methodology are welcome at hello@vidclean.net.

Related reading

We Transcribed Two Million Words. Most Jobs Produced Under a Hundred.

The usage companion to this post: what people actually send to a transcription tool, why more than a third of jobs produce under 100 words, and a duration histogram whose apparent second peak turned out to be an artifact of unequal bucket widths.