When you search online for what defines good code, you get a lot of requirements. It should be easy to read, performant, correct, easy to maintain, well-tested, well-abstracted, on and on. Pick a senior engineer's blog at random and you'll find some version of the list.
If you write code that checks all of those boxes, most people would agree the code you wrote is good. But all of those requirements are downstream proxies. The actual thing they're proxying for is time. Good code saves time. That's it. That's the whole rule.
Every other "good code" property — readability, performance, modularity, simplicity — earns its place in the list only because, somewhere along the way, it saves someone time. And once you see it that way, a lot of arguments about code style stop being arguments about taste and start being arguments about whose time is being saved.
The rules, decoded
The standard checklist maps cleanly onto whose time gets saved:
| "Good code" practice | What sort of time it saves |
|---|---|
| Correct | the user's time |
| Easy to read | the maintainer's time |
| Performant | the computer's time (if you care about it) |
| Well-abstracted | the maintainer's time |
| Simple | your time |
| Well-tested | future-you's time, after the bug ships |
| Documented | the next person's time (often also future-you's) |
That's it. Nothing on the list is sacred for its own sake. Each one is shorthand for "this saves time for somebody, somewhere down the line."
This is also why people tell you not to optimize prematurely. Premature optimization uses a lot of your time, right now, in exchange for relatively minimal gain later — and that's only if you picked the right thing to optimize, which you probably didn't. A lamborghini with no engine always looses to a Nissan Altima that has one.
The time-saved framing also gives you a precedence order that I think most engineers would agree with, even if they wouldn't say it out loud:1
textyour time >= others' time >>> your computer's time > others' computers' time
At least I hope it does. The ">>>" is doing a lot of work there — there's an enormous gap between human time and machine time, and a lot of bad engineering culture comes from forgetting that gap exists.
The corollary: not everything needs to be good
If good code is code that saves time, then code that doesn't need to save much time doesn't need to be very good.
A quick Python utility to process a one-off dataset? Who cares if the indentation would give Guido a stroke, or if the variables have the least inspired names possible, or if the time complexity is worse than bogosort. If you wrote it quick and your computer didn't suffer for too long, you saved time in the long run. This is the whole point of xkcd 1205 ↗ — there's a real budget for how much effort it's worth spending to save effort, and one-off scripts almost never clear the bar for being made pretty.
The mistake isn't writing ugly code. The mistake is writing pretty code when ugly would have been fine, or writing ugly code when it's going to live in production for five years.
Receipts: a TA's tale
Now, in the age of vibe-coded AI slop, the time-saving framing gets weird in interesting ways. Trust me, I was a TA recently, and some of the code I saw could barely be called code anymore. A real example, with the student's prompt and the model's output pasted directly into the submission:
textLearning Outcomes Practice with abstract classes and interfaces Contributingto an existing codebase Following a UML diagram Using the super keywordPracticing encapsulat[ion in] Minecraft. It is not necessary to be familiarwith the video game Minecra[ft]...create the code for this:I'll help you create the code for this Minecraft-style Mobs assignment. Let mebreak this down into the required files and implement each problem.Perfect! I've created all the necessary code files for your Minecraft-styleMobs assignment. Here's what I've implemented:Files Created:- damageable.py — The Damageable interface with an abstract take_damage() method- entity.py — Entity base class with select_adjacent_empty_cell() (Problem 1)- living_entity.py — LivingEntity now implements Damageable (Problem 2)...Key Features Implemented:✅ Abstract classes and interfaces✅ Generic types with Spawner[T]✅ Proper use of super() keyword✅ Encapsulation with private attributes✅ All 8 problems completed
And then, further down in the same file, the assistant's filled-in reflection template:
textMost difficult part: The refactoring problem (Problem 2) with the Damageableinterface and multiple inheritance concernsMost rewarding part: Seeing the generic Spawner[T] work...Learning outcomes: Understanding interfaces, abstract classes, generic types...The reflection is thoughtful and demonstrates genuine engagement with theassignment's learning objectives. Feel free to modify any answers to betterreflect your actual experience!
That student got a pretty solid score. Our autograder spot-checked the code, and nowhere in the TA guide did it say we could fail submissions for AI usage this blatant.
Here's the uncomfortable part: by the "good code = code that saves time" definition, the student succeeded. They got the points. They saved several hours, didn't read a single line of what they pasted, and walked away with the same grade as someone who'd actually learned encapsulation. The code "worked" in the only sense that mattered to them.
The definition isn't wrong. The definition is exactly right, and that's why this stings. Good code saves time for someone, and "someone" in school is the student, not the future maintainer (there isn't one) or the user (there isn't one) or future-them (they're not going to revisit a freshman assignment). When all the downstream stakeholders disappear, the only time left to save is the writer's, and AI slop is extremely good at that.
The lesson isn't that the definition fails. It's that "good code" is relative to who's holding the stopwatch.
A brief and unauthorized history of laziness
If you zoom way out, this is the whole story of computing. You can do anything a computer can do by yourself2 — it might take a year, but you have the benefit of wildly illegal algorithms that your brain somehow executes:
- Is this sorted? Glance at a bar chart that's clearly ascending. Time complexity: O(1).
- Find the minimum spanning tree. A few points positioned so it's obvious it's just a line through all of them. Time complexity: O(n).
- Integrate . ...oh, wait, a computer can't actually do that one.
So we're great at some things. But we don't want to do them repetitively, and we really fall apart on the things our brain's illegal algorithms don't cover. Try multiplying by hand. You don't want to. I don't want to. Nobody wants to.
So in ye olde ages, people in power figured out they could make other people do the work for them. Then we built calculators and computers to delegate one step further. Even so, early machines like the Bombe needed manually substituted rotors every day3 — we were still in the loop, just at a higher level.
Early computers were programmed on tape. People got tired of tape (and tired of swatting literal bugs out of relays), so they moved to other media, and then to assembly, BASIC, FORTRAN. Then people got tired of those and invented Lisp, and later Python. Every layer of that stack is somebody, somewhere, going "I am too lazy to write that the old way" and inventing an abstraction. The history of programming is basically the history of refusing to do the same boring thing twice.
Which loops back to the thesis. Every tool, every language, every framework, every snippet someone publishes on a blog — they all exist because somebody wanted to save time, theirs or someone else's. Good code is just the most recent link in that chain.
So what does this actually change
Reframing "good code" around time saves you a lot of religious arguments.
- "Is this code good?" becomes "whose time does it save, and is that the right person?"
- "Should I refactor this?" becomes "will the time I spend refactoring be paid back by time saved later, and by whom?"
- "Should I write tests for this?" becomes "is this going to break in a way that costs someone enough time to be worth writing tests now?"
- "Should I use this fancy abstraction?" becomes "does it save more time than it costs the next reader to understand?"
None of these have universal answers, which is the point. The same code can be excellent in one context and terrible in another, because the time budget changed.
The one thing that stays constant is the definition. Good code saves time. The proxies — readability, performance, all of it — are just the rules of thumb we've built up over the decades to estimate how much time a piece of code is going to save or cost, before we actually find out.
And occasionally, like with the Minecraft Mobs assignment, the rules of thumb collapse and the raw definition shows through. That's not the definition failing. That's the definition working exactly as advertised, on a problem where the time-saving was pointed in a direction nobody designing the assignment had accounted for.
Worth thinking about, next time someone tells you their code is good.
Notes
-
Sometimes your boss' time comes first, but then there's the question of if that's really just saving you time in the long term by getting you a promotion ↩
-
With an infinite pen, infinite paper, and infinite time. Standard assumptions. ↩
-
They unfortunately didn't value the Wrens' time that much, but at least they realized they didn't need to invent a general-purpose computer a few years early to crack Enigma. ↩