Why are estimations so tough in software development?
1. Introduction
“How long will that take?” - is a question every developer has heard hundreds of times. What comes to mind each time is “it depends…”
I hold a bachelor’s degree in Mechatronic Engineering from Bialystok University of Technology. More than once, I’ve had the chance to design or make something using machining tools – both manual and CNC ones. To visualize how the manufacturing process looks in mechanical engineering, let’s imagine we’re making a flat timber connector with 10 holes in it.
First, a constructor designs the part. He chooses the material, sets the dimensions, and decides where the holes go and how big they are. Then, based on that documentation, a machine operator – whether on a CNC or an old-school manual mill – picks the right tools, feed rates, and all the other necessary stuff to get the job done. The machine cuts the shape out of a sheet of metal, drills the holes, and finishes the edges. Once it’s done, the operator takes out the finished piece and starts on the next one. What’s more, CNC machines can make several – or even a dozen – parts at once, and the whole process can be fully automated. Either way, we can be pretty sure, or at least reasonably expect, that the process will take roughly the same amount of time if we’re using the same setup: same material, same machine settings, same tools. On top of that, modern CNC machines will even tell you exactly how long it’ll take to produce a given part once you load up the program.
In software development that process looks nothing like what I just described and this is exactly why estimating time in IT projects is one of the hardest skills in the industry. There’s no such thing as two identical apps. Every project is unique – with a different design, different assumptions, and totally different business goals. Often, there aren’t any ready-made templates to use, and even the simplest feature can turn out to be a pain to implement in a specific environment.
On top of that, platform differences between Android and iOS tend to mess with our plans pretty often. And to make things even more “fun,” React Native lets you target web apps, Apple Watch apps, or even TV platforms – all from the same codebase.
So then, someone might say that estimations are pointless, or that it's basically just a lottery — but that’s not entirely true.
It doesn’t matter if you’re a developer who needs to estimate or price out a task, or a CEO trying to understand why a “simple” project is taking three months — I hope what you’ll find here will shed some new light on how this whole process actually works.
We’ll start by going over the basics and some key concepts. We’ll dig into what actually makes this so hard, and how to try bridging the gap between the tech world and the business world — which, in my opinion, is one of the most important parts of any IT project.
2. Basic definitions
There’s gonna be a bit of dry theory here, but I’ll do my best to keep it clear and easy to follow 🙂
2.1 Estimation
It’s the process of figuring out how much time, effort, and resources will be needed to complete a given task or project. It’s a key part of planning and project management — it helps set realistic goals and use resources effectively.
Estimation usually isn’t just a one-time thing. It tends to evolve as the project moves forward. It helps us build realistic timelines, set the right priorities, and keep track of progress. It’s also useful for spotting risks early and managing expectations on both sides.
Estimates are usually done by developers or the tech team, and most often expressed in story points, though sometimes you’ll still see hours being used.
Did you know that:
Hofstadter’s Law -Any task always takes longer than you expect — even when you take Hofstadter’s Law into account.
2.2 Pricing
This is the process of turning an estimate into an actual price. It includes the: estimate + hourly rate + margin + risk and it’s an external, contract-related figure. It’s presented to the client and usually negotiated. If your estimate was done in hours, the math is pretty straightforward.
But if you estimated in story points, converting that into hours means you need to factor in the team’s velocity — or take the appropriate assumptions about it if it’s a new project or team and you don’t have that data yet.
2.3 Task
It’s a single unit of work that needs to be done as part of a bigger project. It’s specific and measurable — for example, “Make the login screen background white” is clear enough to understand what’s expected, and you can verify when it’s done.
Often, it’s assigned extra info like who’s responsible, its priority, or status. Tasks like this are used every day to break down big jobs into smaller chunks, and they’re common in tools like Jira, Asana, Trello, or Basecamp.
They’re basically the building blocks of work management.
- Epic: User login flow
- User Story: “As a user, I want to login to access my account”
- Tasks:
- 1. Create a login form (frontend)
- 2. Handle the request (backend)
- 3. Add form validation
- 4. Create unit tests
- 5. Validate UX designs
2.4 Epic
It’s a big, high-level piece of work, usually too large to complete within a single sprint (but not impossible). It represents a business goal — for example, user login in an app. It’s broken down into smaller tasks and user stories.
2.5 Project
A project is a big piece of work with a clear start and finish, aimed at creating a specific solution — like a mobile app. It has a clear business goal, involves people with different roles, and is made up of multiple epics.
Projects can last from weeks to months or even years. These days, they’re often managed using Agile methods like Scrum or Kanban.
2.6 Complexity
This is the level of technical difficulty involved in completing a task, feature, or project. It doesn’t mean how long it will take, but it affects risk, raises costs, and increases the chances of mistakes or changes.
Common factors that add complexity include things like unusual architecture, complicated designs, edge cases, unclear business or tech requirements, new technologies, or just the overall scale of the work.
Does complexity affect the work? Definitely yes. Tasks that take the same amount of time can have very different levels of complexity. Having too many complex tasks in one sprint significantly increases the risk of delays, which in turn pushes up rates and safety buffers. Complexity is usually assessed using story points or other point-based methods like t-shirt sizing or just the Fibonacci sequence. Only after figuring out a task’s complexity can we start to predict how long it’ll take a specific person to complete it. That time depends on the developer’s skills and how well they know the project or technology. For example, a junior might take 5 days to finish a task that a senior can do in 2. From there, by calculating the cost — time * rate + buffer + margin — we can set expectations and assign the right person to the job.
- Task: "Add login via Google account"
- Complexity: 5/6 (requires OAuth, tokens handlers, integrations)
- Time: 3 days for senior developer, 6 days for junior developer
- Cost: 2400€ (senior) vs. 1800€ (junior) - but the senior gets it done twice as fast.
2.7 Storypoint
Story points are used to estimate the complexity, effort, and uncertainty of tasks or user stories. They are not hours, days, or any other unit of time.
They’re usually assigned using the Fibonacci sequence: 0.5, 1, 2, 3, 5, 8, 13, 20, and so on. That’s because in most cases, it’s hard to precisely tell the difference between, say, a 5 and a 6 — but it’s easier for the team to say whether something is a 5 or an 8.
Simply put, a task rated at 5 story points is roughly twice as hard as one rated at 2 points. After using this system for a while, teams can measure their velocity — how many story points they complete per sprint (e.g., 30 story points per sprint).
Story points are a planning tool, not for micro-managing!
Below I've described the basic differences between storypoints and hours.
Tab. 1 Differences between storypoints and hours
Storypoint | Hour | |
---|---|---|
What is it? | Relative unit of complexity | Unit of time |
Who estimates? | Developer team or just one developer (on planning for example) | Developer team or just one developer with a manager |
For what? | Sprint planning, measurement of velocity | Pricing, planning, roadmaps |
Why? | Comparing tasks, predicting performance, estimating task difficulty, and then planning them properly | Estimating the cost of completing a task, project, or feature. Allocating developers time. |
Accuracy | Approximate and resistant to differences in developers skills | Seemingly precise — but can be misleading without data |
When NOT? | Not used for pricing or contracts (e.g., fixed-price), because story points ≠ hours | Don’t estimate on your own without involving developers. |
3. Why is IT so different from manufacturing?
The main difference between IT and traditional manufacturing is that every project is unique. In mass production, we’re used to repeating the same process to make a batch of products, and that process is strictly standardized.
In IT app development, however, there are big differences between clients, their expectations, and the specific requirements of each technology. Because of that, we can only standardize parts of the process — but it will never be a repeatable, assembly-line style production, since every app is different.
I don’t mention the client for nothing — they play one of the key roles in IT. The client isn’t just the end user, they’re an active part of the creation process. Their needs shape the app, and their decisions — often made during development — impact how the work progresses. Developers have to be ready to adapt to changing client requirements throughout the entire process.
Another important factor is the fast pace of technology. In IT — especially in mobile app development — new tools, libraries, and even entire architectures appear week after week. A perfect example is React Native, a technology that has really taken off in recent years, with practically every update bringing something new and innovative. Not long ago, I had to face updating the tech stack in one of the apps I was working on. It turned out that during that time, React Native switched to a new architecture (https://reactnative.dev/architecture/landing-page).
Updating the environment and moving to the new architecture caused many libraries used in the project to lose backward compatibility. This forced me to find new solutions, quickly learn them, and implement them into an already developed environment. What usually takes a few hours ended up taking several days 🙂
Building cross-platform mobile apps comes with another big challenge: the differences between platforms. iOS and Android evolve independently, have different requirements, offer different solutions to the same problems, and can cause unpredictable issues. Seemingly simple tasks can end up delayed significantly due to platform-specific quirks, unexpected bugs, or the need to find alternative solutions. Take, for example, blocking screenshots in an app. On Android, it’s pretty simple — you just add FLAG_SECURE in the MainActivity. On iOS, there’s no native way to do this, so you either use some GitHub solution or write a native method yourself that replaces any screenshot or screen recording with a black screen while the app is running. Sounds easy? But does it still sound that simple when you imagine getting this task as a Junior React Native Developer with only three months of experience and no context? :)
As a result, working in IT means constant learning, adaptation, and flexibility. It’s an industry where relying on fixed patterns and well-trodden paths is difficult. The ability to respond to change and solve problems before they become critical is one of the most important qualities for both developers and companies.
4. Common misconceptions
4.1 “2 developers = 2x faster”
Not necessarily. Breaking tasks down isn’t always possible because some things have to be done sequentially. A great example is building a mobile app from scratch. It’s hard to create a guest filter screen if the guest list doesn’t exist yet or is being worked on by another developer at the same time 🙂 On top of that, there are merge conflicts, code reviews, and synchronization issues. As you can see, that already adds up — and we haven’t even mentioned the most important part: communication, which grows exponentially: 2 people = 1 connection, 4 people = 6 connections.
4.2 “You’ve done it before, so you’ll do it quickly.”
In point 3, I explained the difference between an IT project and manufacturing with a flat timber connector. A similar argument applies here. Every project is different — it has its own architecture, unique requirements, changing technologies, and a different client and business goals.
For comparison, when I was a junior developer, I implemented authentication using Okta OAuth. In the next project, the requirement was to use Azure. I assumed the implementation would be very similar. Unfortunately, I was very wrong. Azure had its own client requirements (which at the time caused issues with React Native), so I had to write a custom solution. This in turn required learning the entire process of attaching and intercepting tokens so that Azure could handle it properly.
The time difference was significant — what used to take about a week with Okta, took up to a month with Azure.
4.3 “It's just frontend”
You can probably guess how often I’ve heard this one :) “It’s just frontend” often means dealing with responsiveness across devices, cross-platform or cross-browser differences, custom animations and components, and various APIs.
5. Summary
Keep these things in mind, and you’ll change your approach to estimation — and the whole industry — by 180 degrees.
- Estimation is an art
Let’s remember there’s no mathematical formula for a perfect estimate. The biggest factor affecting its accuracy is experience. As teams, developers, and managers, we have to accept that mistakes will happen. What matters is learning from them and not repeating them in the future.
- Uncertainty is normal
It’s natural not to be 100% sure about your estimate. That’s why, in my opinion, the best way to communicate is using ranges instead of exact numbers (like 1–2 weeks instead of 8 days). Unknown unknowns will always pop up, so having a buffer for unpredicted situations helps protect the team or developer from negative consequences.
- Communication between developers and business is a key
Developers are the technical experts, while the business side knows the context and priorities. Transparent communication about risks and assumptions, along with understanding business goals, leads to better estimates.
- Document your estimates.
It will help you in the future, and over time you’ll notice which mistakes you managed to eliminate.
- Don’t be afraid to be conservative
It’s better to deliver something earlier than later. Try to add buffers to your estimates. Remember, the client will always be happier if you deliver in 2 days when the estimate was 3 days, rather than delivering in 3 days when the estimate was 2 days :)