Estimating feature work as a web developer
Estimating project timelines in software is an interesting topic to me. As programmers we are used to thinking in concrete, logical terms, yet this can go out the window as soon as we are asked for an innocent time estimate. We are now entering into an ambiguous and uncertain world that nobody prepared us for. It's overwhelming, and it can actually get worse over the years instead of better.
"Hey Will how long would it take to add feature X?"
We are bound at some point to experience the trauma of massively underestimating a large project. When it goes wrong we likely are going to lose some sanity. Maybe our own time an money. Maybe our credibility. We can even start to question if we are cut out for this work after all.
Rather than trying to reinvent the estimate or avoid doing them altogether (though nice ideas) I want to share some practical tips on making more accurate estimates for feature work in a web development context.
First I'll share some ideas about breaking features down into tasks, and second a list of some common estimation gotchas I have run into working as a web developer.
1: Estimating small chunks of work
There are quite a few benefits of breaking down estimates into smaller parts.
Firstly, writing down our thoughts helps us to spot the things that we missed. For our estimates this can mean quickly spotting literal days worth of extra work. It is far too easy to blurt out "Feature X will be about a two days worth of effort" before realising you failed to consider all its tricky edge cases.
Second, it enables us to put a lower bound on the amount of work we are estimating. Suppose I can enumerate N subtasks for the feature I'm estimating. Right away I'll have a quick sanity check that this is least N hours of work. Personally I keep subtasks of 2-6 hours each. I believe the exact range here is something personal and only really comes with experience. If they are much larger than 6 hours I can probably be break them down even more, getting a bettern estimate.
Thirdly, presenting this breakdown to the person who asked for the estimate can be beneficial for the both of you. They might now decide that the scope of the feature should be reduced, or budget from elsewhere should be allocated to support it. Either way, you are now in a better position to ask for more time or money, and they are in a position to be happy about recieving your work.
I like to group tasks under headings like "Frontend", "Backend", "Database" to again guard against forgetting anything. Occaisonally there will be a "Configuration" heading to account for updating any external systems like a CMS, analytics dashboard, or the like.
Example breakdown
Suppose the client wants to add a new feature to delete bingbongs from the bingbong detail modal. Here is what I might write out:
Feature: Deleting Bingbongs Database: * Add migration for Bingbong table with "deleted" and "deleted_at" columns Backend: * Add DELETE /bingbong/:id route Frontend: * Add trash icon button to modal * Connect button with new backend route * Show loading spinner when delete is pending * Automatically close bingbong modal on successful delete * Automatically update bingbong list view to remove deleted bingbong when it is deleted ESTIMATE BREAKDOWN Backend - 3 hours Frontend - 4 hours = 7 hours
2: Common gotchas in feature work
Below are some tasks that I find are commonly hidden in simple feature requests. Being able to spot these early will help you to make your estimates more accurate and minimize surprises when the work is delivered.
Loading states
Is any extra effort going to need to be dedicated to showing loading states in the application? This may include things like:
- Showing a loading spinner when the user submits a form
- Shimmer effects on page load
- Optimistic UI
Error states
Is any extra effort needed to validate, display, and test errors in the application? Here are just a few considerations:
- Showing form validation errors from both clientside and serverside logic
- Handling internal server errors with a toast message or a redirect
- Testing error states that depend on a 3rd party service. Can you easily trigger them for testing?
Scalability (even a tiny bit)
Luckily most of us don't have to worry about scaling our service to handle millions of concurrent users (if we did we would be lucky for another reason!). However there is a class of scaling problems that we can run into with even a few dozen users:
- Does the layout break when there are a few dozen / hundred items to display in a list?
- Do we need to implement pagination to handle? What about a basic search feature to handle? This can balloon in effort pretty quickly.
- For single page applications: does showing the few dozen / hundred items trigger one or more network requests for each one? This can dimish the user experience pretty quickly if not handled carefully.
- On the other extreme: does the layout break when there are zero items to display in a list?
Thinking forward in time
Some features get more complicated when we look forward in time:
- Can a resource become stale while a user is viewing it? E.g. around midnight a list of today's "upcoming" events might become a list of "past" events
- Can a 3rd party cause a resource to become stale? E.g. a user's account integration with an external website may become invalid without us knowning. Will they be stuck with an invalid account integration?
- Is it possible for users to make edits to resources? Can a user undo an edit?
- Is it possible for users to delete resources? Can a user undo a delete?
Addressing bad actors on our platform
If our website allows users to upload text or media and share it with other users we need to account for:
- Having a way to moderate / take down / hide user content manually ourselves
- Allowing a user to block another user that they don't wish to see
Conclusion
In the spirit of keeping this article concise and digestable I'm going to cut myself off here. Though, there is a lot more I want to write about estimates so there is a followup warranted. Hopefully this article gives some food for thought on approaching your own estimates. I encourage everyone to think, and perhaps way more importantly, write, about how you have estimated in the past and what you can do to estimate even better next time.