Pakkit.net
← Back to blog

Engineering Practice

The Job Is Mostly Reading

We picture engineering as typing, but the work that actually determines whether the typing is any good is reading — code, logs, docs, data, the system as it really is — and the engineers who go faster are usually the ones who read more before they write.

  • Engineering Practice
  • Systems Thinking
  • Debugging
  • Craft

The mental image of the job is a person typing — writing code, producing output, making things. That image is mostly wrong, and quietly harmful. The bulk of real engineering, the part that decides whether the typing is any good, is reading: reading the code you’re about to change, the logs the system is producing, the docs and tickets around a problem, the data as it actually is. The typing is the visible tip; the reading is the iceberg. And the engineers who seem suspiciously fast are usually not fast typists — they’re fast because they read enough first to type the right thing once.

You can’t change what you don’t understand

Every change lands in a context that already exists, and that context has opinions. The function you’re editing is called from places you haven’t seen. The config has a default someone chose for a reason. The “obvious” fix collides with a constraint that isn’t visible from where you’re standing. If you start typing before you’ve read enough to know those things, you’re not moving fast — you’re gambling, and the house edge is every assumption you didn’t check. Reading first isn’t caution; it’s the only way to make a change that fits the system instead of fighting it.

Writing code before you’ve read the code is like answering a question before you’ve heard it. You might be right. You’re mostly just lucky.

The reading has layers, and each one is a place people skip

“Read first” isn’t one thing. It’s several, and each is a spot where someone in a hurry cuts the corner that later cuts them:

  • Read the code. Not just the function you’re touching — its callers, its assumptions, the shape of the thing around it. Most bugs I’ve shipped came from changing code I understood locally and not globally.
  • Read the logs and the data. The system is telling you what it’s actually doing; the question is whether you’re listening. And the data rarely matches the mental model — which is its own recurring lesson: survey the data before you act on it, because the schema is intent and the data is reality.
  • Read the docs and the history. The commit that explains why, the ticket with the constraint, the runbook with the gotcha. Someone often already wrote down the thing you’re about to rediscover the hard way.
  • Read the error, all of it. The actual message, the whole stack, the specific line — not the first line and a guess. An enormous fraction of debugging is just reading the error properly.

Reading is faster than the alternative

The pushback is always “there’s no time to read all that, I need to ship.” But reading isn’t the thing that costs time — not reading is. The afternoon lost to a change that broke something three files away. The rewrite of code that already existed because nobody read the module that had it. The outage from a config default nobody looked up. Every one of those is slower than the twenty minutes of reading that would have prevented it. Going fast and reading first aren’t in tension; reading first is how you go fast, because it front-loads the cheap work (understanding) before the expensive work (being wrong in production).

Read before you touch — especially when it’s live

There’s a sharper version of this when the system is running and real: read before you touch, and read in a way that doesn’t itself change anything. When I’m diagnosing something live, the whole first phase is read-only on purpose — look, don’t poke — because a mutating “let me just try…” during diagnosis can destroy the evidence or the system you’re trying to understand. That’s its own discipline: diagnose read-only before you touch anything. The instinct to do something is exactly the instinct to distrust until you’ve read enough to know what doing something will actually do.

Reading is also how you inherit a system

The deepest version of this is joining anything unfamiliar — a new codebase, an inherited service, someone else’s automation. You don’t write your way into understanding it; you read your way in. And it cuts both directions: the reason the author is the worst judge of their own docs is that understanding is invisible from the inside, so the newcomer reading is the one who finds the gaps. Reading is how knowledge actually transfers; writing just leaves the trail.

So I’ve made peace with the fact that a good day might involve very little typing and a lot of reading, and that this is not the day being unproductive — it’s the day being done correctly. The typing is easy and fast once you know what to type. Knowing what to type is the job, and knowing comes from reading. If your best engineering days also look suspiciously like reading days, I’d like to hear I’m not alone.