Iurii RoguliaIurii Rogulia
AboutServicesPricingProjectsStackReviewsPhrasesBlog
Contact
Iuriiย ships.

Iurii Rogulia, IT partner for business & fractional CTO. Professionally building software since 2001.

Think of a number
PricingQuality checklistPrivacy PolicyCookie Policy

Business

TMI Iurii Rogulia
VAT ID: FI29845875
DUNS: 368664211
Lappeenranta, Finland ๐Ÿ‡ซ๐Ÿ‡ฎ

[email protected]
  1. Home
  2. /
  3. Blog
  4. /
  5. Why 'Two Weeks' Always Means Six โ€” and How to Estimate Honestly

Iuriiย Scopes: Why 'Two Weeks' Always Means Six โ€” and How to Estimate Honestly

Estimates don't blow up because developers are bad at math โ€” they blow up for reasons you can name, and work around

July 15, 2026ยท 15 min read

How to estimate software projects honestly: why two weeks becomes six, the iceberg under the happy path, ranges over single numbers, and calibration.

Topics

Fractional CTOProject ManagementSoftware EstimationEngineering PracticeLeadership
Why 'Two Weeks' Always Means Six โ€” and How to Estimate Honestly

On this page

  • The iceberg under "the happy path"
  • Effort is not duration
  • The things you can't estimate because you haven't met them yet
  • Scope creep and the "while you're in there" tax
  • Optimism, anchoring, and the number that bends
  • How to estimate honestly: ranges, not single numbers
  • Decompose until each piece is a day โ€” and time-box what you can't
  • Separate the estimate from the commitment
  • Track estimate vs actual, and trust history over your gut
  • The cone of uncertainty: a stale estimate is a lie
  • Name your assumptions, or the number means nothing
  • The honest-CTO framing: who you can plan around
  • Takeaways

A developer says "two weeks." Six weeks later, it ships.

This happens so reliably that whole project-management methodologies exist mostly to manage around it. And the standard explanations are wrong, or at least lazy. "Developers are bad at estimating" is the comfortable one โ€” it puts the fault in a personality trait, which means nobody has to change how they ask for numbers. It also doesn't survive contact with the evidence: the same developers estimate their commute, their grocery run, and their weekend renovation with the same optimism, and so does everyone else. The bias isn't a coding skill defect. It's structural.

So here is the question worth answering, because the answer is actionable: how to estimate software projects honestly โ€” knowing in advance why the number bends, and giving a figure your business can actually plan against. I've been giving estimates, and being held to them, for a long time. I've been wrong in every direction. What follows is why "two weeks" becomes six, and the specific things I now do to give numbers that don't.

The iceberg under "the happy path"

When a developer pictures a feature and says "two weeks," they are almost always estimating the happy path. The part they can see. User clicks the button, the data is valid, the third-party API responds, the record saves, the page renders. That mental movie runs in a few seconds and feels like the whole job.

It is maybe a third of the job.

Below the waterline sits everything the demo never shows. Input validation. The empty state, the loading state, the error state โ€” three screens nobody mentioned but all of which have to exist. Authentication and authorization on the new route. The database migration, and the rollback for when it goes wrong. Error handling for the API call that times out. Idempotency for the request the user double-clicks. The deploy. Code review, and the round of changes it produces. QA finding the thing you didn't, and the back-and-forth to fix it. Then the second bug QA finds because the first fix broke something adjacent.

None of that is in the two-week movie, and none of it is optional. A feature that handles only the happy path isn't 90% done; it's a prototype that happens to demo well. The gap between "works when I click through it once" and "works in production for strangers doing things I didn't predict" is where the other four weeks live.

This is the single biggest source of estimate error, and it's not arithmetic. It's a perception problem: the part of the work that's easy to imagine is a small and unrepresentative fraction of the part that has to be built.

Effort is not duration

The second structural error is quieter and just as expensive. A developer estimates effort โ€” "this is about three days of work" โ€” and the number gets recorded, and reported upward, as duration: three calendar days, done Thursday.

Those are not the same quantity, and the conversion factor is brutal. Three "ideal days" of focused work do not fit into three working days. They fit into a working week and a half, because the working day is not eight hours of the estimated activity. It's standups and the sync that ran long. It's the context-switch tax every time someone asks "quick question." It's reviewing someone else's PR because the team blocks if you don't. It's the interview you're on the panel for. It's lunch and the commute that lives in the calendar even when remote.

Industry-wide, the gap between ideal engineering hours and elapsed calendar time tends to land somewhere around half โ€” you get roughly four to five productive hours of the estimated work into a nominal eight-hour day, and less on a meeting-heavy one. So an honest effort estimate of "five days of work" is, before anything goes wrong, closer to two calendar weeks of wall-clock time. The estimate wasn't wrong. The translation was missing.

When I give a number now, I'm explicit about which currency it's in. "Five days of effort" and "ready in two weeks" are different sentences, and conflating them is how a correct estimate produces a broken commitment.

The things you can't estimate because you haven't met them yet

The third reason is the honest one, and it's the reason no technique fully closes the gap: you cannot estimate what you haven't discovered yet.

The payment provider's documentation says the webhook fires once. In production it fires three times, out of order, and one of them arrives before the API call that triggered it has returned. The legacy table has a column called status that's authoritative in three places and ignored in a fourth, and nobody alive knows why. The "simple" integration turns out to rate-limit at a number the docs don't mention, discovered only under real load. The third-party API lies โ€” returns 200 OK with an error nested in the body.

These are unknown-unknowns, and they are not a sign that the estimator was careless. They are genuinely invisible at estimation time. You find them by building, because building is the act of discovery. Every non-trivial feature contains some number of these, and the number is itself unknown. This is exactly why I won't quote a rescue engagement before I've spent time in the codebase โ€” most of the cost lives in things the repository hasn't shown me yet, and I wrote up that whole audit method in technical due diligence before a rewrite.

You cannot estimate these away. But you can estimate their existence โ€” you know they're coming, even if you don't know their shape โ€” and that's what a range is for.

Scope creep and the "while you're in there" tax

Then there's the part that isn't a misperception at all โ€” it's the work genuinely growing under your feet.

"While you're in there, can you alsoโ€ฆ" is the most expensive sentence in software, because each instance is individually reasonable and collectively unbounded. The feature that was scoped as one form acquires a second field, then validation on that field, then a special case for one customer, then an admin view to manage the special case. Nobody decided to triple the work. It accreted, one defensible request at a time.

The estimate was honest for the feature that was described. It was never updated for the feature that was actually built, because the growth happened in conversation, not in a ticket. An estimate is a statement about a fixed scope; the moment the scope moves, the estimate is stale and almost nobody re-states it.

Optimism, anchoring, and the number that bends

The last reason is psychological, and the cheapest to fix once you see it.

A stakeholder asks, "this is pretty simple, right?" โ€” and the number bends toward the answer they're hoping for. Not through dishonesty. Through anchoring: the word "simple" is now in the room, and "six weeks" feels like a confrontation, so "a couple of weeks" comes out instead. The developer wants to be helpful and competent, and the social path of least resistance is the smaller number.

Optimism bias does the rest. We imagine the version of the project where nothing goes wrong, because that's the version that's easy to imagine โ€” the failures are, by definition, the things we haven't pictured. So we estimate the best case and report it as the expected case.

The fix is not "be more pessimistic." Pessimism is just optimism's equally uncalibrated twin. The fix is structural, and it's the rest of this article.

How to estimate honestly: ranges, not single numbers

The single most important change: stop giving single numbers. A single number is a lie of precision. It claims a confidence the situation doesn't contain.

Give a range, and attach meaning to its ends. Not "two to six weeks" mumbled as a hedge โ€” that's a single number with anxiety. A real range says what each end means:

Two weeks if the payment integration behaves the way the docs claim. Five if it fights us the way these integrations usually do. My honest expectation is three.

That sentence is more useful to a business than any single number, because it tells the recipient what they're betting on and where the risk sits. If they need it in two weeks, the conversation is now about the payment integration specifically โ€” the actual source of uncertainty โ€” instead of about whether the developer is sandbagging.

If your organization speaks the language, frame it as confidence intervals: a P50 (half the time it's done by here) and a P90 (nine times in ten it's done by here). The distance between P50 and P90 is the most honest thing in the estimate โ€” it's a direct measurement of how much you don't yet know. A wide gap isn't incompetence. It's an accurate report of genuine uncertainty, and a narrow gap on a vague feature is the actual red flag.

Decompose until each piece is a day โ€” and time-box what you can't

You cannot estimate a big thing. You can only estimate small things and add them up. So decompose the work until every piece is roughly a day or less. Pieces that small are things you've done shapes of before; your gut is calibrated on them. "Build the reporting feature" is a guess. "Add the date-range picker, write the aggregation query, build the empty state, add the CSV export, handle the no-data case" is five things you can each actually picture.

The decomposition does double duty: the pieces you can't break down are exactly the risky ones. If you can't decompose "integrate the partner's API" into day-sized chunks, that's not an estimate waiting to happen โ€” it's a research spike. So don't estimate it. Time-box it: "I'll spend one day finding out how this API actually behaves, then I'll estimate the integration." A timebox is a commitment to spend a fixed amount of learning, not a guess at the cost of building. Conflating the two โ€” estimating the build of a thing you don't yet understand โ€” is where the worst overruns come from.

Separate the estimate from the commitment

This is the distinction most teams collapse, and collapsing it is why estimates feel like traps to everyone involved.

The estimate is your honest, technical best guess at the effort. It belongs to engineering. It's a probabilistic statement about uncertain work.

The commitment is the date the business promises to a customer, a board, a launch. It belongs to the business, and it should include a buffer for the risk the estimate just quantified.

These are different objects owned by different people. When a developer's raw estimate gets promised verbatim to a customer as a hard date, the buffer that should have absorbed the unknown-unknowns was never added โ€” and the first surprise blows the commitment. The honest move is to make the seam visible: "My estimate is three weeks. Given what we don't know about the integration, I wouldn't promise the customer anything tighter than five." The buffer is stated, owned, and defensible โ€” not smuggled in by secretly tripling the number, which is the dishonest version everyone resorts to when the seam is hidden.

Related service

Fractional CTO

If your estimates keep arriving as single comforting numbers and landing as overruns, that's a process gap I fix from the inside โ€” separating engineering's estimate from the business's commitment, and putting calibration in place.

More about this service โ†’

Track estimate vs actual, and trust history over your gut

Your gut is uncalibrated until you measure it. The single highest-leverage practice in estimation is also the most neglected: write down what you estimated, then write down what it actually took, and look at the two columns.

After a dozen rows, patterns appear that no amount of careful thinking would have surfaced. You discover you're consistently 2.2x light on anything touching authentication. You discover CRUD features land almost exactly on estimate, but anything involving a third-party API runs triple. That's reference-class forecasting, and it beats fresh judgment every time: "the last three features that looked like this took four weeks each" is worth more than any amount of reasoning about why this one will be different. It usually won't be.

This is also the cheapest competitive edge a team can build. A developer who knows their own historical multiplier gives numbers that come true. One who estimates from scratch every time keeps relearning the same lesson and keeps surprising everyone, including themselves.

The cone of uncertainty: a stale estimate is a lie

There's a well-documented shape to estimation error called the cone of uncertainty. At the very beginning of a project โ€” the idea stage, before anything is built โ€” estimates are reliably off by a factor of around four in either direction. Not because everyone is bad at it; because there's genuinely four-x worth of unknowns still undiscovered. The cone narrows only as you build and learn. By the time you're halfway through, the same estimate might be off by 25%. By the end, it's off by nothing, because it's done.

The operational consequence is blunt: an estimate has a shelf life, and re-estimating at milestones isn't admitting failure โ€” it's the job. The number you gave at the idea stage was your honest best guess given near-total ignorance. Three weeks in, you know things you didn't, and the responsible move is to update the number out loud. A team that holds you to an idea-stage estimate after a month of discovery is asking you to honour a guess made by someone who knew less than you do now.

The opposite failure is just as common: giving the idea-stage estimate, then never revisiting it, and letting it quietly become a broken promise. A stale estimate that nobody updated is, functionally, a lie โ€” not because anyone intended to deceive, but because it stopped describing reality and nobody said so.

Name your assumptions, or the number means nothing

Every estimate rests on assumptions, and an estimate detached from its assumptions is worthless โ€” worse than worthless, because it looks authoritative while being unconditioned.

"Three weeks" means nothing on its own. "Three weeks, assuming the staging environment matches production, the partner's API does what its docs claim, and nobody changes the requirements mid-flight" is a real estimate โ€” because now both sides can see exactly which load-bearing beliefs the number stands on, and watch for the moment one of them fails. When the partner's API turns out to behave differently, you don't have an unexplained overrun; you have a named assumption that broke, and a conversation that starts from "remember assumption two" instead of "why are you late."

I write the assumptions down, next to the number, every time. It's the difference between an estimate someone can interrogate and a number they can only resent when it's wrong.

The honest-CTO framing: who you can plan around

Here is the part that's really about hiring, not arithmetic.

A good engineer โ€” or a good fractional CTO, or a good contractor โ€” gives you a number you can plan around together with its uncertainty. They will tell you the range, name the risk, separate the estimate from the commitment, and update you when the cone narrows. That is not them being evasive or covering themselves. That is them being useful. The uncertainty is real whether or not they tell you about it; the only choice is whether you find out now or in week five. I've written more about what that role actually involves in what a fractional CTO does, and the same posture shows up in the rewrite-or-stabilise decision โ€” the honest answer is the conditional one.

And here is the filter, stated plainly: the client who wants a single small number no matter what the work is โ€” who hears the range and pushes for "just give me one number, just tell me two weeks" โ€” is asking to be lied to. They will get their single small number from someone, because someone will always say what a client wants to hear. That someone will then be late, and the client will be surprised, and the cycle repeats with the next contractor. If you, as a buyer, punish honest ranges and reward confident single numbers, you are training your suppliers to deceive you, and you will get exactly the estimates you've selected for.

The engineer who refuses to compress an honest range into a comforting lie is the one worth keeping. The discomfort of hearing "three to five weeks, here's why" is the price of a number that comes true. I'd rather lose the engagement at the estimate than lose your trust in week six โ€” and a contractor who feels the same way is the one you want holding your timeline.

Takeaways

  • "Two weeks" is the happy path. The iceberg below โ€” validation, error states, auth, migrations, review, QA โ€” is most of the real work and none of the mental movie. Estimate the iceberg, not the demo.
  • Effort is not duration. Ideal engineering hours convert to calendar time at roughly half; say which currency your number is in.
  • You can't estimate unknown-unknowns away โ€” but you can estimate that they exist, which is what a range is for.
  • Give ranges with meaning attached, not single numbers. The distance between P50 and P90 is an honest measure of what you don't yet know.
  • Decompose to day-sized pieces. What won't decompose is a research spike โ€” time-box the learning, then estimate the build.
  • Separate the estimate from the commitment. Engineering owns the honest guess; the business owns the buffered promise. Make the buffer visible, don't hide it in a secret multiplier.
  • Track estimate vs actual and trust history over gut. Your own multiplier on auth, or on third-party APIs, beats fresh reasoning every time.
  • Re-estimate at milestones. The cone of uncertainty narrows as you learn; a stale estimate nobody updated is functionally a lie.
  • Name your assumptions next to the number. An estimate without its assumptions can't be interrogated, only resented.
  • The honest filter: a contractor who gives you a range with its risk is the one to keep. The client who demands a single small number regardless of the work is training their suppliers to lie.
Iurii Rogulia

Working on something like this?

Fractional CTO

If you keep getting estimates you can't plan around โ€” comforting numbers that quietly become triple โ€” that's a judgment problem before it's a coding one. I can sit on your side of the table and tell you which numbers to trust.

More about this service

What clients say

โ€œ

We'd just raised and needed to double the engineering team fast, but nobody internally had hired at that scale or owned the architecture decisions that came with it. A full-time CTO was a six-month search we didn't have time for. Iurii held the role two days a week in the meantime โ€” he set up the interview loop, sat in on the senior candidates, killed a rewrite the team was quietly drifting toward, and made the infrastructure call before it turned into a fire. When we finally hired someone permanent the handover took a week because everything was already documented. He ran it like an owner, not a consultant billing hours.

Kasper Holm ๐Ÿ‡ฉ๐Ÿ‡ฐ

CEO

Topics

LeadershipCTOHiringArchitectureStrategy
โ€œ

I'm a non-technical founder and I'd been making technology decisions by guessing, which was getting expensive. Iurii joined as a fractional CTO one day a week and the difference was immediate โ€” he set up a sane roadmap, vetted two contractors I was about to overpay, and translated what the dev team was telling me into plain language so I could actually make calls. He's not there to write all the code; he's there so I stop making the wrong bets.

Matteo Conti ๐Ÿ‡ฎ๐Ÿ‡น

Founder

Topics

LeadershipCTOHiringStrategy
โ€œ

We had a small in-house dev team and no one senior enough to make the hard architectural calls. Hiring a full-time CTO didn't make sense at our stage, so we brought Iurii in two days a week. Within a month he'd untangled the deployment process, sat in on hiring interviews, and helped the team push back on a feature request from sales that would have cost us six weeks. He treats the role like a partner, not a consultant billing hours.

Joachim Weber ๐Ÿ‡ฉ๐Ÿ‡ช

CEO

Topics

LeadershipArchitectureCTO

Related articles

Hiring Your First Developer: 5 Questions That Filter Out 80%
July 20, 2026ยท 14 min
Hiring Your First Developer: 5 Questions That Filter Out 80%

Hiring your first developer with no technical person in the room? 5 interview questions that filter out 80% โ€” and what a strong answer sounds like.

Topics

Fractional CTOHiringEngineering ManagementStartupsLeadership
Rewrite or Stabilise: The Decision Framework I Use
June 22, 2026ยท 12 min
Rewrite or Stabilise: The Decision Framework I Use

Rewrite or stabilise a legacy codebase? A practical decision framework: when stabilisation wins, when rewrite is justified, and the Strangler Fig middle path.

Topics

Rescue ProjectsTechnical StrategyLegacy CodeArchitectureEngineering Practice
Technical Due Diligence Checklist Before a Software Rewrite
June 10, 2026ยท 17 min
Technical Due Diligence Checklist Before a Software Rewrite

Technical due diligence before a rewrite: a structured 2-hour audit method covering architecture, security, debt, and cost range. What to expect.

Topics

Rescue ProjectsTechnical Due DiligenceEngineering PracticeBest Practices
AI Agent Prompts: Guardrails to Prevent Code Disasters
June 5, 2026ยท 18 min
AI Agent Prompts: Guardrails to Prevent Code Disasters

Keep an AI agent inside your codebase conventions: CLAUDE.md structure, system prompts, mid-session stop prompts, and where lint rules beat text instructions.

Topics

AIEngineering PracticeBest PracticesWorkflowDevOps
AI Coding for Senior Developers: What to Delegate (and Not)
June 3, 2026ยท 16 min
AI Coding for Senior Developers: What to Delegate (and Not)

AI coding workflow for senior developers: what to delegate freely, what to scrutinize, what never to hand off, and the signals that mean stop immediately.

Topics

AIEngineering PracticeWorkflowBest Practices