July 22, 2026

Why 'it'll take a day' always turns into three

Listen to the summary
0:00 / 0:00
Why it'll take a day always turns into three, cover graphic for erkshitiz.com.np

A client asked for a CSV export button on a dashboard, and I said a day, meaning it. Writing the actual export code took about half of one. Then the export needed a field the data model didn’t store yet, which meant a migration and a backfill for existing rows. Then the dates in the export were off by several hours for a handful of accounts, a timezone assumption the rest of the dashboard had quietly gotten away with because it only ever displayed relative time, “3 hours ago,” never an absolute one. Then the client wanted the columns reordered after seeing the first export, a five-minute change that still had to wait for their reply, sit in review, and go out in the next deploy window. Three days, for a button.

The estimate was never wrong about the code

None of that is a story about misjudging how hard CSV generation is, because that part actually took about as long as guessed. The estimate was accurate about the thing it was estimating, it just wasn’t estimating the whole task. “A day” priced the code I could already picture writing before I’d opened the project, and everything that showed up afterward, the missing field, the timezone edge case, the wait on someone else’s reply, was invisible from wherever I was standing when I gave the number. That is not a sign of a bad estimate. It is what an estimate is, structurally: a guess made from outside the problem, before opening it up reveals what was actually in there.

Three separate costs, not one fuzzy multiplier

“It always takes three times longer” sounds like a joke about pessimism, but it holds up because it is really three distinct, recurring costs stacked on top of each other, not one vague fudge factor. There is discovery work, whatever the codebase turns out to actually need that nobody could have listed in advance, a missing field, an assumption baked into a data model, a dependency that isn’t quite what the docs claimed. There is other people’s response time, a review, a design sign-off, a client reply, none of which move at the speed of your own typing and all of which sit on the calendar as elapsed time even though they cost you almost no actual effort. And there is the last stretch of polish, the timezone bug, the empty-state that wasn’t handled, the case that only shows up for one real account out of thousands, the part of “done” that is invisible until the feature is actually in front of real data. None of the three is optional or occasional. They show up on almost everything, which is why the multiplier keeps landing in roughly the same place instead of varying wildly task to task.

The fix is not padding the number

The obvious-sounding fix, just triple every estimate up front, doesn’t actually solve anything, it just relabels the same guess with a bigger number and a false sense of having accounted for the unknown. What changed for me instead was being explicit about which of the three categories a given estimate was actually covering. “A day” for the code I can already see, stated as exactly that, plus an honest flag that discovery, review turnaround, and edge-case polish are separate and not yet counted, rather than folded silently into the same number. A client or a project manager can plan around “a day of code, plus whatever discovery turns up, plus however long your review process takes” far better than they can plan around a single number that quietly promised more than it could see.

What actually helps, working solo

Freelancing alone means there’s no team convention to lean on, no standard “everyone here doubles their gut number,” so the discipline has to be self-imposed. The habit that stuck was giving the code estimate honestly, small and specific, and then separately naming the categories of time a task usually drags in beyond that, out loud, before starting, rather than discovering them mid-task and looking like the estimate was simply wrong. It usually was not wrong. It just was never asked to account for the parts of the work that hadn’t introduced themselves yet.