← બ્લોગ પર પાછા

YouTube Playlist Duration API: How This Tool Works Behind the Scenes

Sharat Sachin 9 મિનિટ વાંચન
youtube api engineering performance

A developer-focused deep dive into how we compute YouTube playlist durations at scale: API pagination, caching strategies, quota management, and rate limiting.

Building a YouTube playlist duration calculator sounds trivial — sum up the video durations — but doing it fast, at scale, and within the API quotas is more interesting than it looks. This post is a developer-focused breakdown of how YouTube Playlist Length works under the hood.

The naive approach and why it fails

If you were sketching this on a whiteboard, you would probably write something like:

GET playlist -> list of video IDs
for each video ID:
    GET video -> duration
    add to total

This works for a five-video playlist. For a 500-video playlist, it costs 500 sequential API calls, each with roughly 100ms of network latency — over 50 seconds end to end. And every video call costs one API quota unit, chewing through the daily 10,000-unit allotment in 20 playlist analyses.

The real approach

Three optimizations turn 50 seconds into 500 milliseconds:

1. Paginated playlistItems calls

The playlistItems.list endpoint returns up to 50 items per page with a nextPageToken for pagination. A 500-video playlist takes 10 page requests, chained (each request needs the previous response's nextPageToken). We ask only for the contentDetails.videoId field to keep the response small.

GET playlistItems?part=contentDetails
    &fields=items/contentDetails/videoId,nextPageToken
    &playlistId=PLxxxx
    &maxResults=50
    &pageToken=<token>

2. Batched videos calls in parallel

The videos.list endpoint accepts up to 50 comma-separated video IDs in a single call. So for 500 videos, we make 10 batched calls — and unlike the playlistItems calls, these have no dependencies on each other, so they run in parallel via asyncio.gather.

chunks = [video_ids[i:i+50] for i in range(0, len(video_ids), 50)]
tasks = [call_youtube_api("videos", video_ids=chunk) for chunk in chunks]
responses = await asyncio.gather(*tasks)

Ten parallel calls all complete in the time of the slowest one — around 200-300ms.

3. Redis-backed caching

Playlists change slowly. Once we have the video list and durations for a playlist, we cache it in Redis for 24 hours. A cached playlist skips the API entirely and returns in ~30ms. Cache key is playlist:<id>, value is a JSON serialization of the video objects.

Cache invalidation is time-based only; there is no invalidation-on-change since we cannot know when a creator adds or removes a video without querying. 24-hour TTL is a reasonable tradeoff — most course playlists are effectively immutable.

API quota economics

The YouTube Data API assigns each Google Cloud project 10,000 quota units per day. Different endpoints cost different amounts:

Endpoint Cost per call
playlists.list 1 unit
playlistItems.list 1 unit
videos.list 1 unit per 50 IDs (batched)

A 500-video playlist analysis costs 1 (playlist metadata) + 10 (playlistItems paginated) + 10 (videos batched) = 21 units. At 10,000 units per day, that is 475 fresh analyses. With cache hits, real-world traffic supports many multiples of that.

To handle traffic spikes, we split traffic across multiple API keys by time-of-day. During peak hours, one key handles evening US traffic while another handles morning APAC. Users can also supply their own key via the form, which runs on their own quota — useful for developers doing bulk analyses.

The stack

For the curious:

  • Backend: FastAPI on Python 3.13
  • Cache: Redis (24h TTL on playlist analyses)
  • Analytics: MongoDB (per-playlist request counters, non-PII)
  • Templates: Jinja2
  • Frontend: Tailwind CSS via CDN, vanilla JS
  • Hosting: Render

The full source code is open on GitHub.

Things I'd do differently

Two ideas on the roadmap:

  1. Server-Sent Events for large playlists. Currently the response is one shot at the end. For a 5,000-video playlist we would want to stream results as each batch completes.
  2. CDN edge caching for popular playlists. The top 100 playlists on the site account for a disproportionate share of traffic. Caching their responses at the CDN would drop Redis load significantly.

Try it

Poke the API by loading any playlist and inspecting the network requests. Or read the source and open a PR.

Related reading

વારંવાર પૂછાતા પ્રશ્નો

Which YouTube Data API endpoints do you use? +
We use `playlists.list` for playlist metadata, `playlistItems.list` for the list of video IDs (paginated 50 per page), and `videos.list` for the actual duration and metadata of each video (batched 50 at a time).
How do you handle API quotas? +
The YouTube Data API gives each project 10,000 units per day. Fetching a 500-video playlist costs roughly 12-15 units. We time-slice across multiple API keys during peak hours, cache aggressively in Redis for 24 hours, and support user-provided keys as a fallback.
How long does the tool take on a large playlist? +
A cold playlist (not in cache) of 500 videos completes in 400-700ms. All the playlistItems and videos API calls run in parallel. A cached playlist responds in about 20-40ms.

Related posts