The Work Nobody Quotes For in a Build Estimate
Estimates are accurate about work that can be pictured and silent about work that only exists once the thing is live. This sheet lists the silent half, explains why each item is systematically omitted, and gives a method for putting it back without inventing numbers.
- Applies to
- Any in-house build estimate for automation that will run unattended
- Inputs you supply
- Your own hours per category and an hourly rate you are willing to state
- Produces
- An adjusted estimate with the omitted categories named and priced
- Out of scope
- Whether to build at all; this sheet only makes the estimate honest
Build estimates miss the same eight categories every time: second environments, credential rotation, dependency upgrades, incident response, the write-up afterwards, interruption cost, handover to a second operator, and eventual decommissioning. None of them is exotic and none of them appears in a normal quote, because a quote prices what can be pictured and all eight only exist after the system is live.
This is not a claim that engineers are optimistic. It is a claim about structure. Ask somebody to estimate writing a thing and they will estimate writing the thing accurately. The omission is the question, not the answer, and the fix is to ask about categories rather than to add a percentage to a number that was answering a narrower question.
Why estimates miss the same things
Three mechanisms produce the same gap regardless of team or domain. The first is that the target is defined as a demo. A demo has no second environment, no credential lifecycle, no alerting and no audience beyond the person running it, so none of that work enters the scope being estimated.
The second is that unscheduled work has no natural unit. You can estimate a feature because it is a thing; you cannot estimate "the upgrade that breaks something in March" because it is an event. Anything without a unit tends to be recorded as zero, and zero is a specific and wrong number rather than an absence of a number.
The third is that the person doing the work is often the person doing the estimating, and they do not invoice themselves. An hour spent on a Sunday fixing a stalled process does not appear in any system, so it never becomes evidence, so the next estimate is made with the same blind spot as the last one.
Quote against reality
The table below is the shape of the gap. It contains no amounts because the amounts are yours; what is portable is which rows exist and why each one is missing from a normal quote.
| Category | In a normal quote | In reality | Why it is omitted |
|---|---|---|---|
| Execution logic | Estimated in detail | Roughly as estimated | Not omitted; this part works |
| Second environment | Absent | Days, then ongoing drift | The demo ran in one place, so one place was scoped |
| Credential lifecycle | Absent | Recurring, plus a spike on any personnel change | Setup is visible, rotation is not |
| Dependency upgrades | Absent | Hours per month, unschedulable | No event to point at when the estimate is written |
| Incident response | Absent | Irregular hours, at bad times | Nobody estimates for failures they have not had |
| Write-up and follow-up | Absent | Longer than the incident itself | Treated as optional until the same failure recurs |
| Handover | Absent | Documentation plus supervised practice | Only becomes visible when the owner is away |
| Decommissioning | Absent | A day of unglamorous work | Nobody plans the end at the beginning |
Getting to a second environment
A system that exists in exactly one place cannot be changed safely, because every change is tested by making it in production. The second environment is what converts a risky edit into a rehearsal, and it is almost never in the estimate because the demo did not need one.
The cost is not only the initial setup. It is the ongoing drift: configuration that diverges, data that is stale, credentials that expire in one place and not the other, and the slow decay that makes people stop trusting the copy. Keeping a staging environment honest is a recurring task, and it is the task most often abandoned first.
Credential rotation and access changes
Creating credentials is a setup task everybody remembers. Rotating them is a recurring task almost nobody schedules, and access changes arrive with every personnel event: somebody joins, somebody leaves, a contractor finishes, a laptop is replaced. Each event touches every system that holds a secret.
For automation that signs transactions the stakes are higher than for a normal application, because the credential is the money. That raises the bar on where it is stored, who can read it, and how quickly it can be replaced if you suspect exposure. Answering "how fast could we rotate everything" honestly is a good test of whether this category has been budgeted at all.
The upgrade treadmill
Dependencies move on their own schedule. Client libraries publish releases with breaking changes, runtimes reach end of support, and the software behind the interfaces you call keeps shipping. The pace is public: browsing the release history of the Agave client repository is a fast way to see that the surface underneath a Solana integration is not stationary.
Upgrades produce no visible benefit when they go well, which is precisely why they get deferred, and deferral compounds in a nasty way. One version behind is routine. Several major versions behind is a project. Far enough behind and the upgrade becomes a rewrite, at which point you are making the build decision a second time with less enthusiasm and the same costs.
The right way to carry this on a sheet is as a standing monthly allocation rather than as an event. Teams that book a recurring slot spend less over a year than teams that batch the work, because batches always land at the worst moment and always exceed the sum of their parts.
Incidents, and the write-up after them
Incident response is the category people accept in principle and still leave out of the arithmetic. The response itself is only the first part: something stops, somebody notices, somebody diagnoses, somebody intervenes. For a system holding funds, the diagnosis often requires reconstructing exactly what happened from records, and reconstruction takes longer than the failure did.
Then there is the write-up, which is the part that decides whether you pay for this incident once or repeatedly. A short record naming what happened, in what order, what condition allowed it and what will change is the mechanism by which a system stops repeating itself. Skipping it is not a saving; it is a decision to buy the same incident again later.
Reconstruction is at least cheaper on a public chain than in a closed system, because a landed transaction is verifiable by anyone and the semantics of what you are reading are documented in the Solana developer documentation. That helps with the chain half of the story. The other half, which is what your own process believed at the time, exists only if you built it.
The cost of the interruption itself
An hour of unscheduled work costs more than an hour of scheduled work, and the difference is not a rounding error. The interrupted task has to be reloaded afterwards, the day it displaced has to be rearranged, and the person carrying the interruption is less effective at whatever they were actually employed to do.
This desk does not publish a multiplier for that effect, because a number invented here would be worth nothing to you. What is defensible is the direction: record unscheduled hours separately from scheduled hours on the sheet, and note that they are worth more. A stack that produces four interruptions a month is more expensive than one that produces four scheduled hours a month, even when the hour counts match exactly.
The line that is easiest to skip and hardest to recover
Interruption cost is invisible in every accounting system a small team uses. It shows up as a founder who is slightly worse at their real job, a project that slips for reasons nobody can name, and eventually as a decision to run the automation at reduced size because supervising it is tiring. All three are costs of building; none appear on any invoice.
What breaks at an inconvenient hour
Automation fails at inconvenient hours for a structural reason: it runs at all hours, and you do not. The specific failures are boring and repetitive. A provider throttles under load. A process exits on an unhandled error and nothing restarts it. A disk fills with logs. A credential expires. A dependency in the network path degrades and everything downstream slows down.
None of these require an exotic explanation, and all of them share one property: they are cheap to fix in daylight and expensive to fix at three in the morning, when the person responding is also the person who built it, is tired, and is working without the checks a normal change would receive. That is the moment when a rushed fix creates the next incident.
The honest question for a build sheet is not whether this will happen but who is awake when it does. That is the point at which the comparison against multi-venue volume automation operated by somebody else stops being about features and starts being about which calendar the failure lands in.
Handover and the second operator
Every system where one person holds the working knowledge has a scheduled outage nobody has written down, timed to that person's next holiday. The estimate to fix it is small and the estimate is still never included, because the problem does not exist on the day the estimate is written.
What makes a second operator real is unglamorous: a runbook that covers start, stop and first checks; a configuration that is documented rather than remembered; credentials reachable without one specific machine; and at least one rehearsal where the second person drives while the first watches. Two hours a quarter buys the ability to be unavailable, which is the whole point.
An illustrative annual hours model
The figures below are placeholders to demonstrate the method. They are not measurements, and they should be replaced with hours you have actually tracked before the total is used for anything.
Illustrative omitted work, per year
Second environment setup: 24 hours once, plus 1 hour per month of upkeep, so 36 in the first year. Credential rotation: 1 hour per month plus 4 hours of personnel-driven change, so 16. Dependency upgrades: 3 hours per month, so 36. Incidents and write-ups: 2 hours per month, so 24. Handover: 2 hours per quarter, so 8. Decommissioning: 8 hours, deferred but real.
Total omitted work in year one: 128 hours. At an hourly rate of H = 60 units, that is 7,680 units of work that appears in no quote. Compare that against the original build estimate on your own sheet; on most small builds it is the same order of magnitude as the build itself.
The comparison at the end of that model is the entire argument of this page. If the omitted categories are comparable in size to the estimated ones, then an estimate that leaves them out is not an estimate with a margin of error, it is an estimate of a different question.
Putting the missing work back
Do this as a structured pass over the estimate rather than as a percentage uplift. Percentages scale with what you already counted; the missing work scales with how long the system runs, which is a different variable entirely.
- List the categories, not the tasks. Use the eight rows in the table above as the starting inventory and add any that are specific to your situation.
- Give each a monthly hour figure. Guess if you must, mark it as a guess, and write the date next to it so the guess can be replaced later.
- Separate one-off from recurring. One-off items belong with the build cost; recurring items belong in the monthly total and get multiplied by the run period.
- Apply a rate you would say out loud. The same rate on both sides of the build-versus-buy comparison, every time.
- Track actual hours for one quarter. Then replace the guesses. After one quarter the sheet stops being an argument and becomes a record.
- Re-run the decision with the corrected numbers. If the verdict changes, that is the sheet doing its job rather than a sign that the first pass was wasted.
The end of the system
Every build sheet should carry a decommissioning line, and almost none do. Systems built for a campaign outlive the campaign, quietly consuming infrastructure and attention. Ending one deliberately means moving funds out, revoking every credential, cancelling the services, exporting whatever records you may need later, and writing down that it is off.
That is roughly a day of work that nobody enjoys and nobody schedules. The alternative is not saving a day; it is an abandoned stack with live keys, an unpatched host and a recurring bill, which is worse than either building or renting and is the most common way small automation projects actually end.
What an honest estimate looks like
An estimate you can defend has four properties. It names the definition of done as an operable system rather than a demo. It lists the recurring categories separately from the one-off work. It states the rate applied to hours. And it carries a date, because every input on it expires.
None of that makes the estimate correct. It makes it checkable, which is the achievable goal. When the real hours arrive, a checkable estimate tells you which category you got wrong and by how much, and that is what turns the second estimate into a better one instead of a repeat of the first with more confidence attached.
Questions this sheet gets asked
Why are software estimates so consistently low?
Because they estimate construction and omit custody. Work that can be pictured gets counted, and work that only appears after the system is live has nothing to picture, so it is not so much underestimated as absent. The fix is structural rather than a matter of adding a percentage: name the missing categories, then estimate each one separately.
Is a contingency percentage enough to cover this?
No, because a percentage scales with the part you already counted, while the missing work scales with how long the system runs. A twenty per cent uplift on a two-week build adds two days; the omitted work is measured in hours per month for years. Add categories, not multipliers.
How do you estimate work that has not happened yet?
Estimate the rate rather than the events. You cannot forecast which upgrade will break, but you can allocate a number of hours per month for upgrades and correct the figure after tracking it for a quarter. A stated rate that turns out to be wrong is still better than an implicit zero.
What is the true cost of an interruption?
More than the time spent on the interruption itself, because the work it displaced has to be picked up again. The point is not to attach a precise multiplier but to record that unscheduled work costs more per hour than scheduled work, and that a stack producing frequent interruptions is more expensive than its hour count suggests.
Should incident write-ups really be in a build estimate?
If the system handles money, yes. Reconstructing what happened, deciding what to change and recording it is the work that stops the same incident recurring, and it takes longer than the incident. Teams that skip it pay for the same failure repeatedly, which is the more expensive option.
How do you price the second operator?
As documentation plus rehearsal rather than as a salary. A runbook, a documented configuration, reachable credentials and one supervised handover session per quarter is the minimum, and it is a few hours per quarter. Compare that against the cost of the system being unavailable for the duration of one holiday.
Does any of this change if the build is small?
The build shrinks and the ownership does not. A small stack still needs environments, credentials, upgrades, alerting and someone reachable, so the omitted categories are a larger proportion of the total on a small build than on a large one. Small builds are where this error does the most damage.
Filed under Running costs by The Build Sheet Desk. Every total on this page is illustrative arithmetic built from inputs printed beside it; none of it is a quote, a benchmark or a figure taken from a real account. How the desk assembles a sheet is written out in the method note.