We ship developer tutorials on a channel nobody outside the company would call famous. Solid mid-size, a couple dozen new subscribers on a good week. For most of last year, our entire notion of "did that video work" was whoever ran the release checking the count a few days later and pasting a screenshot into Slack. That is not measurement. That is a vibe with a timestamp.
The problem with a raw view count is that it only goes up. It is cumulative by construction, so it can never tell you the one thing you actually care about: is this video still gaining, or did it flatline the day the launch tweet fell off people's timelines? The signal lives in the derivative — views per day, per video, tracked from the moment it goes public. Velocity is where you can see a topic actually land versus a topic that just accumulates dust at a slow, respectable rate.
The Tuesday-afternoon version
So of course I decided to build the thing. The YouTube Data API hands you a view count if you ask nicely, and a cron job that writes snapshots to Postgres sounded like a Tuesday afternoon. Here is roughly where I started:
import os
from datetime import datetime, timezone
from googleapiclient.discovery import build
VIDEO_IDS = [...] # our catalog + a few benchmark videos
def fetch_stats(video_ids):
yt = build("youtube", "v3", developerKey=os.environ["YT_KEY"])
out = []
# the API caps id lists at 50, so chunk it
for i in range(0, len(video_ids), 50):
chunk = video_ids[i:i + 50]
resp = yt.videos().list(
part="statistics",
id=",".join(chunk),
).execute()
out.extend(resp["items"])
return out
def snapshot():
ts = datetime.now(timezone.utc)
for item in fetch_stats(VIDEO_IDS):
store_row(
video_id=item["id"],
views=int(item["statistics"]["viewCount"]),
captured_at=ts,
)
This runs. It works on the first try, which is exactly the kind of early success that sets you up for later humility.
Learning the quota ceiling twice
Quota lesson, part one. The Data API doesn't bill you in requests, it bills you in quota units, and the default ceiling is 10,000 units a day. A videos.list call is cheap on paper — one unit per call — but I got greedy. I wanted fine-grained curves, so I scheduled the job hourly across the whole back catalog plus benchmark videos, and I was also, in the same key, running an unrelated search.list experiment. search.list costs 100 units a pop. You can do the arithmetic faster than I did that afternoon. I found out the ceiling existed the way everyone finds out, via a 403 quotaExceeded at 3pm with half the day's snapshots missing and a gap in the data I could never backfill.
The fix was boring and correct: separate the cheap recurring job onto its own key, drop snapshot frequency to something the data actually justified (more on that below), and put the expensive experiments behind a budget I checked before running. I wrote it down. I felt smart.
Quota lesson, part two, which is the one I'm slightly embarrassed about, arrived about six weeks later. I'd overcorrected — went to hourly again during a big launch because I "didn't want to miss the shape of the spike" — and quietly reintroduced the same problem on a different key. Turns out the lesson I'd written down was about arithmetic, and the lesson I actually needed was about restraint. For view counts, hourly granularity is noise. YouTube's own reported counts lag and settle anyway; the number you read at 2pm and 3pm are frequently the same number. Daily snapshots answer every real question, and once-daily is basically free. I did not need the spike in fifteen-minute resolution. I needed to know if the video held for three weeks.
The real work was everything around the API call
Here's the part the API tutorials never mention, and it's the one that actually cost me. The videos.list call was the afternoon project. Everything around it was the real project, and it never stopped generating work:
- joining snapshots against publish dates so I could align everything to "days since release" instead of wall-clock time
- computing per-day deltas without letting a single missed snapshot produce a fake negative
- a comparison view so a new video could be read against the last three of the same type
- a chart the rest of the team would actually open, which meant not Grafana, which meant more work
- some kind of "this one is spiking, look now" nudge
None of that is hard. All of it is maintenance, forever, for an internal tool whose entire user base was five people who mostly wanted a chart on Fridays. I had accidentally become the sole maintainer of a small analytics product, and the roadmap was writing itself in Jira.
Auditing the questions I actually had
At which point I did the audit I'm always telling other people to do, and asked what our questions genuinely were. Written out, they were embarrassingly ordinary:
- Which of the last month's videos are still gaining versus stalling?
- How does this launch compare to the previous one at the same age?
- Did that conference shout-out actually move anything, or did we imagine it?
Those are not exotic questions. They do not require infrastructure I babysit. They require a snapshot history that keeps building on its own and a curve someone else keeps the lights on for.
Moving routine tracking off my plate
So the routine tracking moved to the AllyHub YouTube View Tracker. I pointed it at our channel plus a handful of benchmark videos from adjacent channels — public counts only, nothing you couldn't read yourself — and let it take the periodic snapshots, hold the history, and draw the per-day velocity curves. The part that sold me wasn't a feature on a page. It was that I set it up once as a saved workflow and then stopped thinking about it. It keeps extending the history every day without me rebuilding the reporting layer I'd already rebuilt twice. The setup is the whole cost; after that it just compounds, because it never starts the history over from scratch. The team checks it after each release the way you'd glance at any dashboard, and nobody pings me when a cron job dies, because there is no cron job of mine to die.
Where a hosted tracker earns its place
I want to be fair about the trade, because "just use the hosted thing" is lazy advice on its own. YouTube Studio is still the right tool for deep analytics on your own channel — retention graphs, traffic sources, the swipe-away moment in the first thirty seconds. Nothing external replaces that, and I'd be suspicious of anyone claiming otherwise. Where a self-maintained script or a hosted tracker earns its place is the cross-video, multi-channel history: tracking your stuff and reference videos side by side over months, which Studio doesn't do and which I no longer want to keep an API budget alive for.
And the script isn't dead. It kept exactly one job: a cohort analysis that ties video views to our docs traffic, which is genuinely weird and specific to us, and which no general tool should be expected to do. Stripped down to that single question, the script is actually better than it was when it was trying to be a whole product. Small tools that do one strange thing age well. Sprawling internal tools that do the same four ordinary things every dashboard does are just quota bills waiting to surprise you.
The general shape here keeps recurring in my career, so I'll state it plainly: an API makes data access look free, and then the real bill arrives in the reporting layer nobody scoped in the estimate. Build that layer when your questions are genuinely strange. Ours weren't. They were the same three questions every channel owner asks, asked once a week — and the right answer to a boring recurring question is almost never a bespoke system you personally maintain.
Views on this post will be tracked, naturally. Some habits you keep on purpose.
Top comments (0)