DEV Community

Siya @ Business
Siya @ Business

Posted on • Originally published at contentstats.io

YouTube's API Quota Is 10,000 Units/Day. Here's How I Track 100K Videos Without Hitting It.

If you've ever built anything with the YouTube Data API v3, you've hit the wall.

Google gives you 10,000 quota units per day. Sounds generous until you realize a single search.list call costs 100 units. That's 100 searches per day. For a hobby project, maybe fine. For a production app tracking thousands of videos? Dead on arrival.

I ran into this exact problem building ContentStats — a video analytics API that tracks views, likes, comments, and shares across YouTube, TikTok, and Instagram. I needed to fetch stats for tens of thousands of videos, multiple times per day.

Here's how every endpoint actually costs you, and what I did to solve it.

The Real Cost of Every YouTube API Call

Most developers don't realize how wildly different the quota costs are across endpoints:

Endpoint Cost per Call Calls per Day (10K quota)
search.list 100 units 100
videos.list 1 unit 10,000
channels.list 1 unit 10,000
commentThreads.list 1 unit 10,000
playlists.list 1 unit 10,000
playlistItems.list 1 unit 10,000
videos.insert (upload) 1,600 units 6
thumbnails.set 50 units 200

The problem is obvious: search.list is 100x more expensive than videos.list. If you're using search.list to find videos and then videos.list to get their stats, you're burning 101 units per video. With 10,000 units/day, that's 99 videos maximum.

The Optimization That Saved My Quota

The first thing I learned: never use search.list if you already have video IDs.

videos.list accepts up to 50 video IDs per request and only costs 1 unit. That means you can fetch stats for 500,000 videos per day if you batch them correctly:

// Bad: 1 video = 1 unit
const response = await youtube.videos.list({
  part: 'statistics,snippet',
  id: 'dQw4w9WgXcQ'
});

// Good: 50 videos = 1 unit
const response = await youtube.videos.list({
  part: 'statistics,snippet',
  id: videoIds.slice(0, 50).join(',')
});
Enter fullscreen mode Exit fullscreen mode

With batching, 10,000 units gets you:

  • 10,000 calls × 50 videos per call = 500,000 video stat lookups per day

That's a massive difference from the 99 videos you'd get using search.list.

But There's a Bigger Problem

Even with optimizations, the YouTube API has fundamental limitations:

  1. The quota resets at midnight Pacific Time — not midnight in your timezone. If your users are in Europe or Asia, you'll burn through quota during their peak hours and have nothing left.

  2. There's no webhook or streaming API. You have to poll. If you want hourly updates, you're making 24 API calls per video per day. For 1,000 videos, that's 480 batched requests — 480 units just for one metric.

  3. Requesting a quota increase requires a compliance audit. Google's quota extension form asks for a detailed review of your app, including privacy policy, terms of service, and a video walkthrough. Approval can take weeks to months, and many requests are denied.

  4. Rate limits exist on top of quota limits. Even if you had unlimited quota, you'd still hit per-second rate limits that slow down bulk operations.

What I Ended Up Building

After months of fighting with quota limits, I built ContentStats as a dedicated video analytics layer that handles all of this complexity:

  • No quota limits — track as many videos as you need
  • Hourly snapshots — automatic polling so you don't have to manage cron jobs
  • Multi-platform — same API for YouTube, TikTok, Instagram, and X
  • Simple REST API — one endpoint, one API key, no OAuth flows

Here's what fetching video stats looks like:

curl https://api.contentstats.io/v1/videos/dQw4w9WgXcQ \
  -H "Authorization: Bearer YOUR_API_KEY"
Enter fullscreen mode Exit fullscreen mode
{
  "video_id": "dQw4w9WgXcQ",
  "platform": "youtube",
  "current_stats": {
    "views": 1500000000,
    "likes": 22000000,
    "comments": 3200000
  },
  "tracked_since": "2026-01-15T00:00:00Z",
  "snapshots_count": 720
}
Enter fullscreen mode Exit fullscreen mode

No quota to manage. No OAuth token refreshing. No batching logic.

Practical Tips If You Stick With YouTube's API

If you need to use the official API directly, here are the optimizations that matter most:

1. Cache aggressively

YouTube stats don't change every second. Cache responses for at least 5-15 minutes. Use Redis or even in-memory caching:

const CACHE_TTL = 15 * 60; // 15 minutes

async function getVideoStats(videoId) {
  const cached = await redis.get(`yt:${videoId}`);
  if (cached) return JSON.parse(cached);

  const response = await youtube.videos.list({
    part: 'statistics',
    id: videoId
  });

  const stats = response.data.items[0]?.statistics;
  await redis.setex(`yt:${videoId}`, CACHE_TTL, JSON.stringify(stats));
  return stats;
}
Enter fullscreen mode Exit fullscreen mode

2. Only request the part you need

Each part parameter doesn't cost extra quota, but it does increase response size and latency. Only request statistics if that's all you need — don't include snippet, contentDetails, etc.

3. Use fields parameter to reduce payload

const response = await youtube.videos.list({
  part: 'statistics',
  id: videoIds.join(','),
  fields: 'items(id,statistics(viewCount,likeCount))'
});
Enter fullscreen mode Exit fullscreen mode

4. Monitor your quota usage

Go to the Google Cloud Console to see real-time quota consumption. Set up alerts at 80% usage so you don't get surprised by a quotaExceeded error at 2 AM.

5. Use multiple API keys (carefully)

Each Google Cloud project gets its own 10,000 unit quota. You can create multiple projects and rotate keys. Google doesn't explicitly prohibit this, but it's a gray area — don't abuse it.

The Quota Costs Cheat Sheet

Here's the full reference I wish I had when I started. Bookmark this — you'll need it.

Operation Method Quota Cost
Search videos search.list 100
Get video details videos.list 1
Get channel info channels.list 1
List comments commentThreads.list 1
List playlist items playlistItems.list 1
Post a comment commentThreads.insert 50
Upload a video videos.insert 1,600
Update video metadata videos.update 50
Set thumbnail thumbnails.set 50
Create playlist playlists.insert 50
Rate a video videos.rate 50
Live chat messages liveChatMessages.list 5

The quota resets daily at midnight Pacific Time (PT). You can check your current usage in the Google Cloud Console.

For the full breakdown with more optimization strategies, I wrote a detailed guide on the ContentStats blog.

TL;DR

  • YouTube API gives you 10,000 units/day
  • search.list costs 100 units (the trap most developers fall into)
  • videos.list costs 1 unit and accepts 50 IDs per call — use this
  • Batch requests, cache responses, only request fields you need
  • If you need to track thousands of videos without quota headaches, check out ContentStats — it handles all the polling, batching, and multi-platform complexity for you

I'm building ContentStats — a video analytics API for developers who need to track video performance across YouTube, TikTok, Instagram, and X. Try it free.

Top comments (0)