Numbering things

There’s an old joke that the two hardest problems in computer science are cache invalidation, naming things, and off-by-one errors.

Nobody talks about the third-hardest problem: numbering things.


Naming things gets all the philosophical attention. Entire blog posts about whether it should be getUserData or fetchUserRecord. Heated Slack threads about whether the module is called utils or helpers or common. Fair enough — names carry meaning, and bad names lie.

But numbers are supposed to be simple. Sequential. Objective. You’d think counting would be the one thing engineers couldn’t mess up.

You’d be wrong.


Start with version numbers. Semantic versioning exists. It’s a spec. Major dot minor dot patch, clear rules about when to bump what. And yet: Chrome is on version 136. Firefox is on 138. These numbers communicate nothing. They’re just counters that go up, like a deli ticket machine that never resets.

Then there’s the other direction — products that version so cautiously they never leave single digits. You’ve seen the roadmap slide: “Version 2.0 — coming soon.” It’s been coming soon for three years. The current release is 1.14.7. At some point 1.x stopped being a version number and became a lifestyle.


The real pathology is final.

Every developer has a folder somewhere — maybe it’s a design file, maybe it’s a deploy script, maybe it’s a whole repo — with names like:

config_final.yaml
config_final_v2.yaml
config_final_v2_ACTUAL.yaml
config_FINAL_USE_THIS_ONE.yaml

final is not a version. It’s a prayer. It’s the developer saying “I want to stop thinking about this now.” And it never works, because the person who named it final is never the last person to touch it.

The same instinct produces new. new_parser.py. Which works great until someone writes a newer parser and now you have new_parser.py and new_parser2.py, and the old new_parser.py is the oldest file in the repo.


Some people don’t version at all. They just overwrite. The file is called deploy.sh and it has been deploy.sh through nine different architectures, four cloud providers, and a mass extinction event in the org chart. You want the version from before the migration? Good luck. It’s the same filename. Git knows, but the person who needs it doesn’t use git.

This is the numbering equivalent of naming your kid “Baby” and never updating the birth certificate.


Dates as versions seem like they’d solve everything. 2026-05-22_release. Unambiguous. Sortable. Except people are inconsistent about formats — 05-22-2026 vs 2026-05-22 vs May22 vs 22May26 — and now your sorted directory listing is an archaeological dig.

And dates don’t tell you magnitude. Was the May 22nd release a typo fix or a database migration? The number is precise about when and silent about what.


The deeper problem is that numbering requires a system, and systems require agreement, and agreement requires caring about something that feels trivial. Nobody wants to be the person who calls a meeting about version numbering conventions. So everyone invents their own, locally, and the collision happens later — when two teams merge repos, when the client asks “which version are we running,” when the deploy pipeline has to sort artifacts and v2 comes after v10 because string sorting doesn’t know about integers.


There’s a number that every project finds eventually: the one nobody can agree on.

Was the MVP “version 1”? Or was it “version 0.1”? The thing before the rewrite — does that count? Some teams start at zero. Some start at one. Some start at one but call the first release “2.0” because marketing decided that “1.0” sounds unfinished.

Windows went from 3.1 to 95 to 98 to 2000 to XP to 7 to 8 to 10 to 11. The logic connecting those numbers is: there is no logic. They’re marketing decisions wearing engineering clothes.


The number one problem in computer science is naming things.

The number three problem is numbering things.

If that bothers you, you’re starting to understand the problem.