Thoughts
We keep trying to make the two hours faster when the problem is the nine days.
“How long will it take?”
I’ve been developing for more than 25 years and I’m comfortable saying that it’s difficult to commit to an answer.
You’d think I’d be better at it by now.
We’ve invented Agile, Scrum, story points, planning poker, velocity, burndown charts and increasingly sophisticated project management software. We’ve broken projects into epics, stories, tasks and subtasks.
And eventually somebody still needs to put a number in a spreadsheet.
Three to five days.
Which has an alarming tendency to become:
Thursday.
Look up the definition of estimate
An estimate is an approximate calculation or judgement.
Approximate.
That’s important.
Somewhere between the developer making an educated guess and the project being sold, an estimate has a habit of becoming a commitment.
A developer thinks something will probably take three days.
Three days goes into the estimate.
Three days goes into the proposal.
Three days goes into the project plan.
Someone calculates a delivery date.
The client makes plans around it.
And suddenly something that began as “I reckon about three days” has become “this will be finished on Thursday.”
The developer hasn’t become any more certain.
We’ve just progressively removed the uncertainty from the language.
We research and develop at the same time
Software development is one of the few industries where we routinely do research and development simultaneously.
When a developer starts a task, they don’t necessarily know exactly how they’re going to solve it.
They probably know roughly.
They’ve solved similar problems. They know the language, framework and architecture. They can make an informed judgement about the likely amount of work involved.
But some of the knowledge required to accurately estimate the work will only be discovered by doing the work.
That’s the paradox.
The best time to accurately estimate a piece of development is often after you’ve finished it.
Which isn’t particularly useful commercially.
“You’ve done this before”
This comes up a lot.
“You’ve built websites before. Why can’t you estimate this one accurately?”
Because we haven’t built this website before.
If it already existed, you probably wouldn’t be asking us to make it.
Experience absolutely improves estimation. If I’ve implemented something twenty times, I have a much better idea of how long the twenty-first will take.
But software projects contain different combinations of requirements, designs, technologies, integrations, content and people.
And the genuinely valuable bits are often the things that haven’t been done before.
There’s an odd relationship between innovation and predictability.
The more certain we are about exactly how to build something, the less novel it probably is.
A website is making a CMS look like a design
That’s deliberately reductive.
But it’s also surprisingly useful.
A huge proportion of website development is essentially:
Take this design and make the CMS produce it.
Which raises an awkward question.
How are we supposed to accurately estimate the development before we’ve seen the creative?
Agencies do it all the time.
We know there will be a homepage. Some landing pages. Content pages. Navigation. Forms. Components. Responsive behaviour.
We’ve built hundreds of them.
But the development complexity isn’t determined by the fact that it’s a website.
It’s determined by what the website is being asked to do.
A design can turn what sounded like a completely conventional content block into something requiring complicated responsive behaviour, animation, unusual content relationships or a CMS model nobody anticipated.
Two websites with almost identical sitemaps can require wildly different amounts of development.
Yet commercially, we’re regularly asked to price the second one before anyone has designed it.
Developers estimate effort. Everyone else hears duration.
There’s another problem.
Ask a developer how long something will take and they’ll generally estimate the work.
That’s perfectly reasonable.
But it’s rarely what they’re actually being asked.
The developer is thinking:
I need to change the data model, update this component, add the endpoint and write the tests. Three days.
Everyone else hears:
It’ll be finished in three days.
Those are completely different statements.
The actual project might involve waiting for access, getting information from the client, an undocumented API behaving differently in production, another project becoming urgent, feedback arriving late, a requirement being misunderstood, someone being off sick, meetings, approvals and something completely unrelated breaking.
Developers don’t tend to include existential factors in their estimates.
But existential factors are often what determine whether something actually gets delivered on Thursday.
Break it down until it feels ridiculous
There are ways to get better at estimating.
One rule I’ve used with development teams is that if a task is estimated at more than half a day, it probably hasn’t been broken down enough.
Not because every task genuinely takes four hours or less, but because breaking work down forces you to think about what you’re actually going to do.
Take something completely trivial.
Fill the car with screen wash.
Thirty seconds?
Open the bonnet. Open the cap. Pour in the screen wash. Close the cap.
Done.
Except, where is the screen wash?
Do we have any?
If not, where are we buying it from?
Where are the car keys?
Has anyone actually opened the bonnet on this particular car before?
We did it on the old car, but this one works differently.
Where’s the bonnet release?
Is the cap stuck?
Fine. We’ve found everything. We’ve filled it.
Are we done?
Do we need to tell somebody it’s done? Are they available? Do they need to check it before we move on?
Then somebody tries the washers.
Nothing happens.
Were the jets working before?
Nobody knows.
We investigate.
Actually, the jets work, but they’re badly aligned. Most of the screen wash is going over the roof.
Now we have a conversation.
“I thought you were sorting the screen wash?”
We filled the screen-wash reservoir.
“But I can’t wash the windscreen.”
The jets need adjusting.
“Why wasn’t that included?”
Because you asked us to fill the screen-wash reservoir.
“Well obviously the point of filling it was so I could wash the windscreen.”
Fair enough.
“Why is this costing more money?”
Because aligning the jets wasn’t in the estimate.
“So you’ve charged us to fix the screen washers and they still don’t work properly?”
No. We charged you to fill the screen-wash reservoir.
“That’s not fit for purpose. We’re not paying.”
FML.
And there, in a completely ridiculous example, is a surprising amount of software development.
The individual task might genuinely take thirty seconds.
But the task is not the whole job.
There is discovery, access, dependencies, assumptions, communication, testing, acceptance and the enormous question of whether the person doing the work and the person asking for it actually have the same definition of done.
That’s why breaking work down matters.
If you can’t describe how you’re going to spend the time, you probably don’t understand the task well enough to confidently estimate it.
Development can fill almost any estimate
Software has another peculiar characteristic.
It is possible to fill almost any amount of time you give it.
Give me a day to solve a problem and I’ll find a solution that takes a day.
Give me a week and I’ll probably make it better.
Give me a month and we can investigate edge cases, improve the architecture, increase test coverage, optimise performance, improve accessibility, refactor the surrounding code and deal with some technical debt while we’re there.
None of those things are necessarily wasted effort.
That’s the problem.
There is almost always another legitimate improvement that could be made.
So when we add contingency to an estimate, we’re not necessarily protecting empty space.
Software can consume the contingency.
If we’re not clear about what done means, development expands to fill the time available.
Contingency doesn’t make an unknown known
The traditional answer is to add contingency.
Estimate the project and add 20%.
There’s nothing inherently wrong with that. Contingency is sensible.
But it’s worth being clear about what we’ve done.
We haven’t made the estimate more accurate.
We’ve made the budget more tolerant of the estimate being wrong.
Those aren’t the same thing.
And because development can legitimately consume almost any amount of available time, contingency needs protecting too.
Otherwise the five-day task becomes six days because six days were available.
Then the genuinely unexpected thing happens on day seven.
Two hours of development. Nine days of delivery.
At Halo, we accidentally ended up with some useful data about this.
We had a fairly enormous Trello bill, so we moved to a self-hosted open-source alternative. As part of the migration we brought across years of historical project data.
That meant we suddenly had a record of how work actually moved through the agency.
We gave the data to AI and started asking questions of it.
One result stuck with me.
For relatively small support requests — tasks involving a maximum of a couple of hours of actual development — the average time from request to sign-off was nine days.
Not nine days of development.
Nine days to get a couple of hours of development through the system.
A request comes in.
Client services needs to understand it.
Development might need to look at it before it can be estimated.
The estimate goes back to client services.
The estimate goes to the client.
The client approves it.
The work gets scheduled.
A developer does the work.
It goes back for review.
The client reviews it.
There might be an amendment.
The amendment gets made.
It goes back again.
Eventually somebody signs it off.
Somewhere in the middle of all that, a developer did two hours of development.
The work around the work
The task doesn’t sit quietly while all this happens either.
It has a narrative.
It comes up in stand-up.
“Still waiting for sign-off.”
Someone sends a chasing email.
It comes up again the next day.
“Did we hear back from them?”
Another email.
Someone updates the ticket.
Someone tells client services.
Someone asks the developer whether it’s finished.
The developer explains that it’s finished but hasn’t been approved.
Someone checks whether it can be closed.
It can’t.
None of those individual interactions is particularly expensive.
But multiply them across hundreds of support requests and suddenly a huge amount of agency time is being spent talking about work rather than doing the work.
And this meta-activity extends well beyond development.
A project needs a third-party service.
The agency puts it on a company credit card because the work needs to move.
Now somebody needs to record that cost.
An invoice needs raising.
Someone needs to process it.
Someone needs to check whether it’s been paid.
If it hasn’t, somebody chases it.
Client services gets involved.
Finance gets involved.
A trivial external cost can generate more organisational activity than the thing itself cost.
All of this is part of delivering software.
Almost none of it is in the developer’s estimate.
We keep trying to make the two hours faster
This is what makes conversations about development productivity interesting.
The two hours of development are visible.
They’re estimated.
They’re scheduled.
They’re put against a budget.
They’re probably recorded on a timesheet.
So naturally, that’s the bit we try to optimise.
Can the developer do it in 90 minutes instead of two hours?
Can AI make them 30% faster?
Can we improve their utilisation?
Meanwhile the task still takes nine days.
Saving half an hour of development has almost no effect on the thing the client actually experiences.
They experience nine days.
There can be far more opportunity in improving everything around development than there is in making developers type code faster.
Reduce the hand-offs.
Get the right information at the beginning.
Make estimates easier to approve.
Give people authority to make small decisions.
Make ownership clear.
Remove unnecessary sign-offs.
The interesting metric isn’t always how long development took.
Sometimes it’s how long the organisation took to deliver two hours of development.
The client is part of the estimate
There’s another uncomfortable truth about estimating software:
The only time we’ll know exactly how long it takes is when it’s signed off.
Because delivery time isn’t entirely in the hands of the development team.
Does the team have the correct information?
Do we have the content and assets?
Can we get answers when questions arise?
Is somebody available to review the work?
Does feedback arrive this afternoon or next Monday?
Is that feedback consolidated, or are five stakeholders reviewing independently?
Can somebody actually make a decision?
And perhaps most importantly: how invested is the client in getting the thing delivered?
I’ve worked on projects where clients turn feedback around in hours, answer questions immediately and make themselves available when the team hits a blocker.
Those projects move incredibly quickly.
I’ve also worked on projects where a development task takes two days and three weeks to get signed off.
The development estimate wasn’t necessarily wrong.
Two days of development still took two days.
But the project didn’t take two days.
Estimation is a shared responsibility
The agency has responsibilities.
We need to ask the right questions, expose dependencies, communicate clearly, manage the work properly and flag uncertainty rather than hiding it inside an optimistic number.
But the client is part of the delivery system too.
If you want certainty around deadlines, you need certainty around the things the development team depends on.
Correct information.
Timely decisions.
Available stakeholders.
Fast sign-off.
And genuine investment in the task itself.
You can’t disappear for a week during a two-week project and still expect the original delivery date to remain untouched.
This isn’t about assigning blame when a project slips.
It’s about recognising that delivery is collaborative.
The fastest projects I’ve worked on aren’t simply the ones with the fastest developers.
They’re the ones where everybody involved is helping remove uncertainty as quickly as it appears.
Waterfall really means fixed price
We spend a lot of time talking about Waterfall and Agile as development methodologies.
In agency life, I think there’s often a more practical distinction.
Waterfall means fixed price.
Agile means time and materials.
That’s deliberately simplistic, but commercially it’s often much closer to the truth.
Fixed-price work demands certainty.
We agree what we’re going to build, agree what it costs and then try to control change tightly enough that those two things remain compatible.
Define everything.
Estimate everything.
Agree the price.
Build it.
Agile accepts something much closer to the reality of software development:
We’re going to learn things while we’re doing it.
Priorities can change. Solutions can evolve. Something we thought was important might turn out not to be. Something apparently trivial might turn out to be extremely valuable.
But somebody still has to pay for that uncertainty.
Time and materials makes that easier because the client is buying the team’s time rather than purchasing a precisely defined output for a precisely defined price.
Neither model is inherently better.
They simply put the risk in different places.
With fixed price, the agency takes much of the estimation risk.
With time and materials, the client takes more of it.
Calling one Waterfall and the other Agile can sometimes make what is fundamentally a commercial decision sound like a philosophical one.
Agile didn’t solve estimation
Agile gave us much better ways to deal with uncertainty.
That’s not the same as removing it.
Breaking work into smaller pieces helps.
Short iterations help.
Regular releases help.
Velocity can help.
Talking to each other definitely helps.
But none of these techniques allows us to see the future.
Sometimes we’ve turned estimation into increasingly elaborate rituals without addressing the fundamental problem.
Planning poker is still a group of experienced people making an educated guess.
It’s potentially a better educated guess.
It’s still a guess.
The easy thing might be the hard thing
There’s a brilliant XKCD comic I’ve thought about for years.
A developer is asked to build an app where a user takes a photograph and the software determines whether they’re in a national park.
Easy enough.
Then they’re asked whether the app can determine if there’s a bird in the photograph.
The response is essentially:
I’ll need a research team and five years.
To the person requesting it, recognising a bird sounds like the smaller requirement.
Technically, at the time the comic was written, it was enormously more difficult.
AI has made that particular example hilariously dated.
Which actually proves the point even better.
Technical complexity isn’t intuitive.
It isn’t even permanent.
Something virtually impossible ten years ago can be an API call today.
Something that looks like a tiny visual change can require restructuring half an application.
That’s why experienced technical people sometimes give surprising answers to apparently simple questions.
Experience doesn’t let you predict the future
After 25 years, I don’t think I’m necessarily dramatically better at predicting exactly how long software will take.
I am much better at recognising where the uncertainty is.
That’s probably more valuable.
I know which apparently simple requirements make me nervous.
I know when an integration needs investigating before I’ll put a number against it.
I know when creative is likely to determine development complexity.
I know when a developer’s three-day estimate probably means three days of uninterrupted development rather than delivery by Thursday.
I know when the estimate depends as much on the client’s availability as the developer’s.
And I know when there’s enough uncertainty that pretending otherwise is going to cause trouble later.
That’s what experience gives you.
Not certainty.
A better understanding of uncertainty.
So what actually helps?
None of this means we should give up estimating.
Over the years I’ve developed a few rules that make it less painful.
Think about the existential factors
Don’t just estimate the code.
What has to be true for the work to happen?
Do we have access? Content? Data? Designs? Credentials? Third-party documentation? Is another developer going to need to review it? Does somebody need to deploy it? Who signs it off?
Think about the things surrounding the task, not just the task itself.
The developer might need two days.
That doesn’t necessarily make it a two-day job.
If you don’t know, buy some certainty
Sometimes you simply don’t know how to solve the problem yet.
That’s fine.
Don’t disguise the uncertainty by putting a suspiciously precise number against it.
Sell some prototyping or discovery time.
Walk a mile in the problem’s shoes.
Spend a day or two investigating it. Try the difficult integration. Build the risky bit. Test the assumption everyone is quietly hoping is true.
Then come back with something concrete.
That time isn’t wasted or additional to the project.
It’s part of the project.
Fold it into the overall cost.
A substantial proportion of a project’s budget can legitimately be spent before production starts — scoping, discovery, solution design, prototyping and documenting what we’re actually going to build.
It can feel difficult to sell because the client understandably wants to spend their money on the thing.
But spending money reducing uncertainty can be considerably cheaper than discovering halfway through the build that everybody was wrong.
Contingency is contingency
If the estimate is ten days and you’ve allowed two days of contingency, the development team has not been given twelve days.
They’ve been given ten.
Work to the original estimate.
Protect the contingency for the things you didn’t know about when you made it.
Otherwise development will happily consume twelve days and the genuinely unexpected problem will arrive on day thirteen.
Contingency isn’t extra development budget.
It’s the money you’ve set aside because you accept that your estimate might be wrong.
Break things down
The more granular the estimate, generally the more accurate it becomes.
If I see a development task estimated at more than half a day, my instinct is that it probably needs breaking down again.
What are you actually going to do during those eight hours?
Breaking the work apart forces you to expose assumptions and dependencies that disappear inside a task called “Build account area — three days.”
But don’t underestimate the cost of doing this either.
A genuinely detailed estimate takes time.
If you want somebody to think carefully through every part of a complex build, investigate the unknowns, identify dependencies and produce a defensible estimate, that’s work.
Accuracy isn’t free.
The level of estimation should be proportionate to the size and risk of the decision you’re making.
Consider the client tax
Some clients make projects move faster.
Some don’t.
That’s not a criticism. It’s a project constraint.
Are they engaged?
Do they have an internal owner?
Can that person make decisions?
Will they have the information we need?
Can we expect feedback tomorrow, or does everything need to go through a committee that meets every second Thursday?
Are there five stakeholders likely to provide five different sets of feedback?
We account for technical dependencies all the time.
Client availability is a dependency too.
A highly engaged client can make an ambitious deadline realistic.
A disengaged client can make a generous deadline impossible.
Price the work around the work
For small support requests, consider a minimum charge from the moment the request enters the system.
Think of it as a call-out fee.
The development might only take fifteen minutes, but the agency has already incurred a cost before a developer touches it.
Someone receives the request.
Someone understands it.
Someone creates the task.
Someone gets an estimate.
Someone sends the estimate.
Someone gets approval.
Someone schedules it.
Someone checks it.
Someone gets sign-off.
Someone invoices it.
Someone checks the invoice has been paid.
Charging only for fifteen minutes of development means the agency is subsidising everything surrounding those fifteen minutes.
Retained clients don’t need this.
That’s one of the advantages of a retainer: the commercial machinery has already happened, so a fifteen-minute job has a much better chance of actually being a fifteen-minute job.
Tax individual purchases
The same principle applies when the agency buys third-party services on behalf of a client.
If somebody asks the agency to put a £20 service on a company credit card and recharge it, don’t invoice £20.
Someone has to make the purchase.
Someone records it.
Someone tells finance what it was for.
Someone adds it to an invoice.
Someone sends the invoice.
Someone reconciles the payment.
And in the meantime, the agency has funded the client’s purchase.
That activity has a cost.
Add a transparent administration charge or markup.
Better still, where practical, get the client to own and pay for their own services directly.
The principle is simple:
If a process consistently creates work, either remove the process or price the work.
Pretending the meta-activity is free doesn’t make it free.
Don’t sell Agile at a fixed price
If you’re selling a precisely defined outcome for a precisely defined amount of money, you’re not transferring much of the benefit of Agile to the client.
You’re accepting the flexibility while retaining the commercial risk yourself.
The client can change priorities, explore ideas and respond to what you learn — but the agency still has to somehow land on the number agreed months earlier.
Something has to give.
If the client wants genuine flexibility, sell the commercial model that supports it.
Time and materials.
A sprint budget.
A retained team.
A retainer.
Agree the amount they’re comfortable investing and continuously put that investment towards the most valuable work.
Sell retainers
For ongoing development, retainers solve a surprising number of these problems.
You don’t need to turn every two-hour support request into a miniature procurement exercise.
You don’t need:
request → estimate → approval → scheduling → development → invoice.
The client has already bought access to an agreed amount of capacity.
Priorities can change.
Small jobs can just get done.
Investigation can happen without somebody needing to approve a £200 estimate first.
The relationship shifts away from buying individual outputs and towards deciding where the available development time creates the most value.
It doesn’t remove the need to estimate.
But it changes what the estimate is for.
Instead of:
How much will this cost?
It becomes:
Is this the best use of the time we’ve got?
That’s a much more useful question.
So how long will it take?
We still need estimates.
Clients need budgets. Agencies need proposals. Teams need plans. Businesses need to know whether an idea is commercially viable.
“It’ll take as long as it takes” isn’t useful.
But neither is pretending an estimate is something it isn’t.
The answer might be five days.
It might be three to eight days.
It might be we need to spend two days investigating this before I can responsibly answer you.
Or it might be:
It’s two days of development. How long it takes to deliver depends on what happens around those two days.
Sometimes the most useful thing a technical lead can do is resist the pressure to provide false precision.
Because an estimate isn’t a promise.
It’s the best judgement we can make with the information we currently have.
We estimate the work. We only know how long it took when it’s signed off.
And if you really need it on Thursday, that’s a different conversation.