Benchmark · Latency · Comparison
Why YouTube Transcript APIs Slow Down on New Videos and Small Channels
Most transcript APIs are fast on videos someone already asked for. Here is why new uploads and small channels are different, how to test any API on them, and what we see in real traffic.
· 5 min read · YTAPI
If you're building something on YouTube transcripts, the videos your users ask for are probably not the famous ones. They're last night's livestream, a lecture from a university channel with 2,000 subscribers, every sermon a church has uploaded, a trading course nobody outside its niche has heard of.
That matters, because a transcript API that looks fast in a demo can be slow on exactly those videos. This post explains why, shows how to test any API on them in a few minutes, and shares what we see in our own traffic. We make one of these APIs, YTAPI, so weigh our numbers accordingly.
Cached and uncached are two different products
Most transcript APIs keep a cache. When a video has been requested before, the API returns the stored transcript, usually in well under a second. When it hasn't, the API has to fetch the captions from YouTube right then, through whatever network it uses, and that is where providers differ.
Popular videos are almost always in some provider's cache, so homepage latency numbers, which tend to be measured on well-known videos, mostly describe cache hits. New uploads and small channels are almost always cache misses.
In our benchmark on uncached videos, we sent the same recent, low-view videos to three APIs from four regions:
| First-try success | Median | P99 | |
|---|---|---|---|
| YTAPI | 100% | 644 ms | 2.34 s |
| TranscriptAPI | 85% | 2.41 s | 9.57 s |
| Supadata | 100% | 4.76 s | 37.2 s |
TranscriptAPI was fast whenever its cache had the video (a 418 ms median on those), but 15% of first requests for uncached videos came back as 408. Its documentation says to retry them, and once we did, the wait for a transcript grew to a P99 of 21.5 seconds. Supadata answered every request, but one in ten took longer than 15 seconds.
None of this shows up if you only test with popular videos.
What real traffic looks like
The benchmark was our own test. Real usage looks the same, only more so. In early October 2026, over 99% of our customers' transcript requests were for videos we had never fetched before. The workloads were what you'd expect: whole channels in a niche, back catalogues of small creators, playlists from course channels. A cache barely helps with any of that.
Those uncached requests took a median of under 300 ms on our servers, with the 99th percentile under a second. That's server time only. From a client, add your network round trip; our four-region benchmark, network included, measured 644 ms at the median. In the same period our servers returned no 5xx errors. About one request in seven was a 404, for videos that were members-only or had no captions. Those are free.
How to test any API on cold videos
You don't have to take our word for it. Pick videos that are unlikely to be in anyone's cache, and time the first request.
- Find fresh, low-view videos. Use videos uploaded in the last few days with few views. Videos uploaded in the last hour often have no auto-generated captions yet, so a week is a safer window.
- Time the first request, not an average over repeats. The first request is the cold one.
- Request the same video again. The second request is a cache hit, so it shows what the API is like on videos someone already asked for. Most APIs, ours included, are quicker the second time. What matters is how long the first request takes, and how often it fails.
- Count first-try failures, such as timeouts and
408, separately from "no captions" answers, and note how long the retries take.
Here is a small script that does this with YTAPI. Change transcript() to call any other API with the same video IDs and compare the numbers. It uses about 41 credits, which the 200 free credits cover.
import os
import statistics
import time
import requests
API = "https://api.ytapi.dev/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['YTAPI_KEY']}"}
# 1. Fresh videos: uploaded this week.
res = requests.get(
f"{API}/search",
headers=HEADERS,
params={"q": "tutorial", "type": "video", "upload_date": "week", "limit": 20},
timeout=30,
)
res.raise_for_status() # a wrong key or a rate limit stops here with a clear error
video_ids = [item["id"] for item in res.json()["items"] if item.get("type") == "video"]
def transcript(video_id):
"""Swap this for the API you want to test."""
return requests.get(
f"{API}/transcripts",
headers=HEADERS,
params={"video_id": video_id, "format": "text"},
timeout=60,
)
def timed(video_id):
start = time.monotonic()
response = transcript(video_id)
return response.status_code, (time.monotonic() - start) * 1000
first, second, failed, no_captions = [], [], 0, 0
for video_id in video_ids:
status, ms = timed(video_id)
if status == 404:
no_captions += 1
continue
if status != 200:
failed += 1
continue
first.append(ms)
status, ms = timed(video_id)
if status == 200:
second.append(ms)
print(f"videos: {len(video_ids)}, no captions: {no_captions}, failed first try: {failed}")
if first:
print(f"first request: median {statistics.median(first):.0f} ms, max {max(first):.0f} ms")
if second:
print(f"second request: median {statistics.median(second):.0f} ms")Look at the first-request numbers. An API that relies on its cache shows it there: first requests take seconds, or come back as timeouts you have to retry. When we ran this script from a server in Germany on October 7, 2026, YTAPI's first requests had a median of 360 ms and a maximum of 1.2 s, with no failures, across 20 videos (one had no captions). The second requests, served from our cache, had a median of 127 ms.
How YTAPI handles a cold request
We cache transcripts too, but nothing depends on it: a video we haven't fetched before is fetched from YouTube when you ask for it, through our own proxy network. If a fetch is slow or refused, we retry it on our side before we answer, within the same request. You don't get a 408 to retry, you don't need a retry loop, and a request that fails in the end is free. A video that has no captions, or is private or members-only, gets a clear 404 that says why, and that's free too.
So new uploads, small channels and long back catalogues behave the same as famous videos. If that's what your users ask for, it's worth testing for. The 200 free credits are enough to run the script above a few times.
FAQ
Why is the second request faster on some APIs?
The first request missed the provider's cache and was fetched from YouTube; the second was served from the cache. Every API with a cache is faster the second time. The useful number is the first request: if it takes several seconds or fails often, the API is fast mainly on videos someone already requested.
Does YTAPI work on videos uploaded today?
Yes, as soon as YouTube has captions for them. Creator-uploaded captions are available right away. Auto-generated captions can take a while after upload. Until YouTube has them, the request returns a 404 and costs nothing.
Do I need to retry failed requests with YTAPI?
No. Slow or refused fetches are retried on our side before we respond. Only a 429, meaning your key is over its rate limit, asks you to wait and try again.
How do I get every transcript from a small channel?
List the channel's uploads, then send the video IDs as a batch. Transcripts for a whole channel or playlist walks through it.