In October I wrote about the three caps that are not the same number: the YouTube Data API's daily quota, the separate bucket search calls draw from, and our own caps a little under both, because a failed request costs quota too.

Last week our allowance went up. The pool went from 10,000 units a day to 60,000, and the search bucket from 100 calls to 1,100. In a well-built system that is a one-line commit.

It was seven files and thirteen lines, and I want to go through them, because the split is the interesting part:

 README.md | 2 +- src/app/admin/runs/page.tsx | 2 +- src/db/schema.ts | 2 +- src/lib/limits/counters.ts | 8 ++++---- src/lib/pipeline/run.ts | 2 +- src/lib/youtube/client.ts | 2 +- src/lib/youtube/quota.ts | 8 ++++---- 7 files changed, 13 insertions(+), 13 deletions(-) 

Four of those thirteen lines are numbers the program reads. One is a sentence that stopped being a sentence. Eight are prose: seven comments and a line of README.

Nakodo is the app this is in, and the public page about how it works describes the behaviour those numbers pace, which is the only place a customer ever meets them.

The four real lines

export const DAILY_QUOTA = 60_000; export const DAILY_SEARCHES = 1_100; 
const CAPS = { youtube: 59_500, youtube_search: 1_095, ... } 

That is the whole behavioural change. The first pair names what the provider allows. The second pair is what we stop at.

The sentence that stopped being a sentence

The admin run log had this heading, and I had typed the numbers into it by hand in some earlier week:

lede="Background work runs every 5 minutes in small batches. YouTube allows 100 searches a day, plus 10,000 units for everything else at 1 unit a call." 

It is now this:

lede={`Background work runs every 5 minutes in small batches. YouTube allows ${DAILY_SEARCHES.toLocaleString("en-US")} searches a day, plus ${DAILY_QUOTA.toLocaleString("en-US")} units for everything else at 1 unit a call.`} 

Of the thirteen lines, this is the only one that is a genuine improvement rather than a correction. The others fixed a number that had gone stale; this one made a sentence that cannot go stale again.

The general version of the lesson: a number typed into a user-visible string is a comment with a worse failure mode. A stale comment misleads the next developer who reads that file. A stale sentence in the interface misleads the person using the product, keeps misleading them, and nothing in the toolchain will ever mention it. There is no compiler warning for prose.

Seven comments, and why I changed them anyway

The remaining prose lines are comments in four files:

// search.list results (1 call each from YouTube's 1,100-a-day search bucket), or 
// Stages that spend the 60,000-unit pool. When it runs out these wait for the // reset; searches (their own bucket), contact lookups, rationales and scoring // carry on. 
// Tracks units spent from the 60,000-unit pool during one run, for the run log. 
 // YouTube Data API (src/lib/youtube/quota.ts): the 60,000-unit pool every // method but search draws on, and search.list's own 1,100 a day. Stopped // short of both, since failed requests cost quota too. 

An argument I have had with myself and lost: comments should not repeat a constant, because then the constant has two homes. The counter-argument that wins is that these comments are read by somebody deciding whether a line of code is safe to change, and "the 60,000-unit pool" tells them the scale immediately in a way DAILY_QUOTA does not. A schema comment about a cache table is not going to make the reader open two other files first.

So they repeat the number on purpose, and the price of that is being in this commit. 8.7 per cent of the lines in this repo are comments, and I know from auditing them that 41 of them contain the word "because". A comment that carries a number is paying rent, and the rent is a diff like this one.

The two numbers that stop the work are not the two numbers with names

Here is the part I only noticed while writing this post. Grep the whole app for the constants:

lib/youtube/quota.ts:11 export const DAILY_QUOTA = 60_000; lib/youtube/quota.ts:12 export const DAILY_SEARCHES = 1_100; app/admin/runs/page.tsx:12 import { DAILY_QUOTA, DAILY_SEARCHES, quotaStatus } app/admin/runs/page.tsx:92 const usedPct = Math.min(100, (quota.used / DAILY_QUOTA) * 100); app/admin/runs/page.tsx:99 lede={`... ${DAILY_SEARCHES.toLocaleString("en-US")} ...`} app/admin/runs/page.tsx:108 / {DAILY_QUOTA.toLocaleString("en-US")} units app/admin/runs/page.tsx:119 / {DAILY_SEARCHES}. 

Every reader is one admin page. The two exported constants named after the provider's quota are display values, and nothing else in the app consults them. What actually stops a run is CAPS in the counters module, which is where 59_500 and 1_095 live, and the relationship between the pairs exists only in a comment.

Nothing prevents the two from drifting. Raise DAILY_QUOTA and forget CAPS and the app keeps stopping at the old number while the admin page cheerfully reports a bigger denominator. Raise CAPS and forget DAILY_QUOTA and the app spends past what the provider allows, and starts collecting 403s that cost quota as well.

The test file next door has three tests, and they are all about the Pacific midnight reset surviving daylight saving:

test("reset works across the DST change", () => { const now = new Date("2026-11-01T06:00:00Z"); // Oct 31, 23:00 PDT const reset = nextQuotaReset(now); assert.equal(pacificDay(reset), "2026-11-01"); assert.equal(reset.toISOString(), "2026-11-01T07:05:00.000Z"); }); 

Not one of them asserts that our cap is below the quota it is meant to stay under. That is the test this commit should have come with, and it is two lines:

assert.ok(CAPS.youtube < DAILY_QUOTA); assert.ok(CAPS.youtube_search < DAILY_SEARCHES); 

Better still, derive one from the other and delete the possibility: youtube: DAILY_QUOTA - 500.

The bug a fourth digit revealed

Look at that grep again, at lines 108 and 119:

<span className="..."> / {DAILY_QUOTA.toLocaleString("en-US")} units</span> 
Searches: <span className="tabular-nums">{quota.searchesUsed}</span> / {DAILY_SEARCHES}.{" "} 

Three of the four display sites format the number. The fourth prints it raw, so the page now says 1100 where the sentence above it says 1,100. Before this commit the value was 100, which looks identical either way, so the inconsistency was there for weeks and could not be seen. A number only has formatting bugs once it is big enough to need formatting.

There is a second disagreement in the same card. The progress bar divides by the provider's quota:

const usedPct = Math.min(100, (quota.used / DAILY_QUOTA) * 100); 

and the sentence underneath it counts down to our own cap, 59,500. So the bar reaches 99.2 per cent at the exact moment work stops and the line below it says zero left. Both are defensible on their own and together they are a contradiction, and the fix is to pick one meaning of "full" for a card that is 30 lines long.

The eighth file

After the commit I grepped the repo for the old numbers to check nothing was left behind. Everything in src was clean. One hit outside it:

docs/design-direction.md:500: - **Quota meter.** 100 ticks, one per search unit of 100, filled in ink. Big Newsreader numeral "2,262" with "/ 10,000 units" muted. The caption reads "57 more searches today. Resets at midnight Pacific." 

That is the 794-line design report that chose this app's colours and components, and the mockup in it has a quota meter with the old denominator, a count of ticks that assumed a 10,000 pool, and a caption promising 57 more searches when the real answer is now over a thousand.

A design document describing an interface is prose about numbers, same as a comment, except that nobody ever greps it. Keeping it in sync line by line is not worth doing, and leaving it as it is means the next person to read it builds the wrong meter. The fix I am taking is one line at the top of that section saying the figures are illustrative and that the live values come from src/lib/youtube/quota.ts, which is the only true thing a frozen document can say about a moving number.

The summary I would put on a sticky note

A constant has a blast radius made of sentences. For this app, raising one number meant:

  • 4 lines of code
  • 7 comments
  • 1 README line
  • 1 hardcoded interface string, which is now computed
  • 1 design document, still wrong, to be labelled as illustrative
  • 2 bugs found, both only visible because the number grew a digit
  • 1 test that should exist and does not

Thirteen lines in the commit, and the commit is the smallest part of it.