This article contains the same content as we share it internally for making time estimates. It is especially written for developers, and we share it to give back to the community by making the life of other developers easier 🙂. If you don’t have experience with development: feel free to read how we do it, but be prepared for some tech terms. You can also contact our sales team if you want the business explanation.
In the following article I will share our insights and steps for accurate time estimations. At the end there’s a checklist to provide a full overview. But first, let's talk about why making estimates is often so hard for developers.
Why making time estimates is hard
If you are a developer, it is quite likely that you find it mildly rude when you are yanked from the comfort of your coding environment and thrown into the cold and unforgiving world of hours estimates. Suddenly you need to make guesses based on incomplete information and then discuss your guesses with people that don't fully understand what you are doing and why. There are new terms and concepts casually being thrown around, and the air reeks of the unavoidable enthusiasm that comes with starting a new project.
Of course you want to go back as soon as possible to your natural environment of solving problems, instead of creating potential future problems. And this is where things sometimes start going wrong.
From the stressful estimate-making mindset, it is easy to remember your normal, comfy development mindset in a more positive light. Development process suddenly seems easier than it actually is, because, after all, it's your daily job, unlike this strange estimate-making business. And just having this kind of emotional background makes you more prone to cognitively discount the hardships that might occur along the way, while overestimating the ease of the development flow
💡 Longing for your cozy development process while trapped in the uncomfortable world of making estimates makes you underestimate problems that you encounter during development while overestimating the ease with which you solve them.
How might you go about fixing this? One approach could be to try making the hours estimation a more comfortable experience (scented candles and all). However, regardless of how comfortable and used to it we are, it is still going to happen in a context that is different from development context, resulting in a skewed perception of development. So our best weapon against it is to be aware and remind each other of the existence of this effect.
Proposed Solution and Other Problems
These are my two cents on how to make the estimation process as painless as possible.
1. List the features and how they relate to the app flow
Identifying and listing major features should be done independently from the concrete "screens" of the app, since the screens are most likely to be subject to change and a small modification in designs could wreak havoc in the way features are implemented.
However, it is important to view the features through the lens of the app flow. This will help you properly scope and architect them. For example, your approach to making a "shopping cart" feature would be different if it was only used in an isolated part of the app, compared to it being expected to be shown and updated across many different sections of the app.
A nice way to strike a balance between ignoring and overly relying on designs is using low-fidelity wireframes while making estimates. This way you would not get stuck in the details of designs, while at the same time keeping in mind how the feature you're estimating is related to other aspects of the app.
💡 List the features you will need to implement based on low-fidelity wireframes. Don't estimate them in isolation or based on detailed designs.
Common pitfall: Don't estimate based on finished designs
Estimating based on fully finished designs is not a good idea. Here are a few important reasons why:
- There will always be hidden features that you will overlook. The existence of a feature might be obvious to the client or the designer, but you might miss it if you don't know what to look for. Don’t assume things, always ask confirmation of what features need to be implemented.
- Finished designs make you focus on what the finished product will look like, not on the process of getting there. It often happens that you see a visual component that you can reuse between different screens (as you should), but forget to mentally account for the time and effort needed to create that component in the first place.
- Even when they are clickable mockups, designs are completely static compared to the app you will be making. This means that they hide away the complexity of all the strange paths users might decide to take to accomplish their goals in your app, and having to account for those paths might come up as a nasty surprise later in the development process.
- Designers mostly focus on happy-paths and perfectly formatted data. Looking at designs makes you more likely to overlook all the work that needs to be done to implement error states and empty states and how they are displayed in the app. You will also need to account for misbehaving data: the designer picked the perfect font size and typeface for that title, but it is you who will need to make design decisions and compromises for when the title can't fit neatly on a single line.
2. Pick one to three risky things
Even if you are completely confident that you have all the tools and skills needed to build that app, make a point of listing several areas where there's a risk of things going wrong.
Risks can come from anywhere. It might be something obvious like using technology that you haven't used before, or building for a niche audience that you haven't had experience with. For example, if you're making an app that handles medical data, the first time around you might underestimate the amount of guidelines you will have to conform to. Or if you're creating an app that will be used by an audience different from you (e.g., children or elderly), there might be additional rounds of feedback that you cannot anticipate.
An obvious risk for an app is relying on a third-party SDK for core functionalities, especially for non-open source SDKs. You cannot estimate time needed for fixing errors that you didn't make in the first place, but you need to account for the time it will take you to debug and determine that your software misbehaving is not due to the code you wrote, but is the fault of the SDK.
Aside from third party SDKs (software development kits), third-party backend developers (e.g., the client wants you to make an app that uses their proprietary API) can also present a likely point of failure for your estimations. Unlike your normal, garden-variety in-house backend developers, third-party backenders' motivations are not fully aligned with yours (i.e., they want to make their own lives easier more than they want your app to succeed). You will also spend way more time than you expect trying to reach them and waiting for their replies, not to mention refreshing hoping for changes they promised to publish last Tuesday.
💡 Try to think of all the hidden stuff that you cannot do anything about, but will inevitably suck up time and mental energy from your development process.
Common pitfall: Don't let yourself be overconfident
This part of the estimation process mostly ties to the first part of this article: when taken out of your development context and dropped into an environment when there's time and endless possibilities, it is easy to underestimate all the things that can go wrong. After all, you are now way more experienced than during your last project, what could go wrong?
The purpose of identifying risks is to break your positive outlook on the project and make you think about what could go wrong, even if you are confident that you know exactly what you're doing. Especially if you think you know exactly what you are doing.
3. Pick an area to focus on
In an ideal world, with infinite time and skill available, you would make a delightful, robust, pixel-perfect app in no time.
But since we are not living in that world just yet, we need to wisely choose the battles we are going to fight during the development process. Realistically, you can make an app that fully features one, or at most one and a half of the following qualities:
- Robust: In theory, all apps should be unbreakable, but in practice some corners are often cut. Think about what you would expect the app to do if the API returns an unexpected response during a transaction, or if you try to do an action that you are not authorized to do in the app, or if your internet connection suddenly drops. Ideally, you would like to see an elegant error message that tells you exactly what went wrong and what you can do to fix it. In reality, you are often presented with a screen (or, god forbid, an intrusive pop-up) that tells you that "Something went wrong" and offers a "Refresh" button if it's feeling generous that day. This is because proper error handling is a time-expensive endeavour and requires a lot of thinking ahead for displaying errors that you hope your app won't encounter in the first place!
- Pixel-perfect: Designers are a talented bunch of people, and it's always sad when we have to twist their ideas to fit the imperfect world that our apps are dealing with. Things like screen sizes and pixel densities, missing or unexpectedly formatted data, individual user's accessibility settings... all conspire to make our apps look clumsy (at best) on all but a selected few devices. It is possible to remedy this, but it requires a lot of time and patience from both developers and designers.
- Quickly made: Most of the apps would benefit from being already available to users, but the next best time to publish apps is "as soon as possible". Making apps quickly doesn't always refer just to the calendar time, but can sometimes be related to the client's hours budget. The point is that even if we know of a better (more robust or more maintainable) way to implement a feature, sometimes there's just not enough time to do so.
💡 Pick one (and a half): robust, pixel-perfect, or quickly made app.
Identifying which qualities of the app should come first will help explicitly align your client's business goals with your team's approach to developing the app, therefore making the estimate more accurate.
Common pitfall: Unaligned expectations
If the client is not familiarised with these trade-offs in advance, they may end up having a different product than they expected. This can result in lengthy and most often unplanned rounds of feedback after the app was delivered, increasing time costs for everyone involved.
On the other side, having the team know what their shared focus should be prevents team members from (implicitly) focusing on different qualities of the app, which could result in an inconsistent app. Knowing what areas are to be paid close attention to also streamlines the code review process, ultimately saving time.
4. Making and estimating issues
Now is the time to actually do the estimates. Depending on which phase of the project you're in (initial estimates before the project is signed, or more detailed estimates right before the development starts) your issues are going to have different granularity, i.e., be more or less detailed and precise.
Try to split the list of features that was created in the first step into manageable chunks of work, and then, well, make an educated guess. Keeping in mind everything that was said so far should go a long way towards preventing you from being unreasonably optimistic, but it's still best to tread carefully.
💡 Time for educated guesses.
There are plenty of techniques for making the actual estimates (think planning poker, t-shirt sizes, the bucket system... the list goes on). Which you choose is up to your team. Different techniques have benefits of their own, but just following them blindly (without previous preparation) probably won't get you where you need to be.
Common pitfall: Unhappy paths
Make sure that your issues (user stories) also encompass everything that could go wrong.
💡 As a user, I want to [...] when the app can't fetch my data, so that I could still accomplish my goal / get information about how to fix my issue.
5. Ask for a second (and third) opinion
When you are focused on getting the job done right (and as quickly as possible), it is easy to overlook entire classes of problems or a not-so-obvious solution. This is why having a colleague (preferably another app developer, but any second pair of eyes is better than none) look over your estimates can cast light on parts of the process that you missed or misjudged due to the tunnel vision or inherent biases.
Checklist for development time estimations
Estimating the time it takes to make an app, or any other software product, is hard. Having a checklist of sorts can make it seem a bit more manageable, so next time you're estimating a project try to use the following checklist to make sure you don't miss anything:
- List features and how they fit in the app flow
- Identify the riskiest parts of the process, even if you don't think anything is really risky about it
- Pick a thing to focus on: robustness, pixel-perfection, or doing it quickly
- Split list of features into rough issues and estimate those
- Ask for (at least) a second opinion
There's seven million (I counted!) other things that can go wrong in any given project, but having a set of guidelines can help us not make mistakes that can commonly be avoided. Eliminating generic pitfalls also frees up mental space for thinking about project-specific risk and how we might work to prevent them from happening.