86

Recently I started working on a project where a very old monolithic application is being migrated into microservice-based architecture.

The legacy codebase is very messy ('spaghetti code') and often an apparently-simple function (e.g named as "multiplyValueByTen") later reveals itself as "thousands of lines of validation code involving 10 tables across 3 different schemas".

Now my boss is (rightly) asking me to estimate how long would it take to write feature X in the new architecture. But I'm having difficulties coming up with a realistic estimation; often I hugely underestimate the task due to reasons I've stated above and embarrass myself because I can't finish in time.

The sensible thing might seem to really get into the code, note every branch and calls to other functions and then estimate the time cost. But there is really a minuscule difference between documenting the old code and actually writing down the new version.

How should I approach a scenario like this?

While I perfectly understand how legacy code refactoring works, my question is not about "how to do refactor/rewrite?" but about giving a realistic answer to "how long would it take to refactor/rewrite part X?"

  • 37
    Make estimates with wide margins, not with single values; e.g 5 to 15 days – Richard Tingle Feb 13 '17 at 8:32
  • 32
    @JuniorDev: why do you think it is "unacceptable for a non-technical team leader"? He might not like your answer, but if you can give no better estimation, it is often to tell the person straight, instead of trying to please him now by a too low estimation and tell him after 5 days, sorry, we only completed the task to 30%. – Doc Brown Feb 13 '17 at 10:12
  • 13
    "The sensible thing might seem to really get into the code, note every branch and calls to other functions and then estimate the time cost. But there is really a minuscule difference between documenting the old code and actually writing down the new version." -- hahahahahahahahahahahahahahahahahahahaha heh. heh. So, it may seem like that, but when you clean up some legacy code, it turns out that the quirks handle issues you had never heard of in cases you had never considered. Or patch over bugs elsewhere. Or are a bug, but bugs that other parts of the code relies upon existing. – Yakk Feb 13 '17 at 20:02
  • 27
    I'll let you in on a little secret: if your manager is asking a junior dev to make a technical estimate, then one of two things is true: he knows you don't know how to make a true estimate and is making it a teaching opportunity, or he's an inexperienced manager and thinks that a junior dev can do it. I've never seen a junior dev that could do it, including (especially?) myself when I was a junior dev. – corsiKa Feb 14 '17 at 5:35
  • 27
    6 to 8 weeks, as we all know. – Matthieu M. Feb 14 '17 at 7:55
111

Read Bob Martin's "Clean Coder" (and "Clean Code" while you're at it). The following is from memory but I strongly suggest you buy your own copy.

What you need to do is a three point weighted average. You do three estimates for each piece of work:

  • a best case scenario - assuming everything goes right (a)
  • a worst case scenario - assuming everything goes wrong (b)
  • the actual guess - what you think it probably will take (c)

Your estimate is then (a+b+2c)/4

  • No it won't be accurate. There are better ways of estimating but this method is quick, easy to understand and mitigates optimism by making you consider the worst case.
  • Yes you will have to explain to your manager that you are unfamiliar with the code and that it is too unpredictable for you to make firm, accurate estimates without spending a long time investigating the code each time to improve the estimate (offer to do this but say you need n days just to give a firm estimate of how many more days it will take). If you are a "JuniorDev" this should be acceptable for a reasonable manager.
  • You should also explain to your manager that your estimates are averaged, based on best case, worst case and probable case and give them your figures which also gives them the error bars.
  • Do NOT negotiate on an estimate - if your manager tries to use the best case for every estimate (they are a fool - but I've met some like that) and then bully / motivate you into trying to hit the deadline, well, they're going to be disappointed sometimes. Keep explaining the rationale behind the estimates, (best case, worst case and probable case) and keep getting close to the weighted average most times and you should be OK. Also, for your own purposes, keep a spreadsheet of your estimates and add your actuals when you've finished. That should give you a better idea of how to adjust your estimates.

Edit:

My assumptions when I answered this:

  1. The OP is a Junior Developer (based on the chosen username). Any advice given is not therefore from the perspective of a Project Manager or Team Lead who may be expected to be able to carry out more sophisticated estimates depending on the maturity of the development environment.
  2. The Project Manager has created a Project plan consisting of a fairly large number of tasks planned to take several months to deliver.
  3. The OP is being asked to provide a number of estimates for the tasks they are assigned to by their Project Manager who wants a reasonably accurate number (not a probability curve :)) to feed into the project plan and use to track progress.
  4. OP does not have weeks to produce each estimate and has been burned before by giving over-optimistic estimates and wants a more accurate method than sticking a finger in the air and saying "2 weeks, unless the code is particularly arcane in which case 2 months or more".

The three point weighted average works well in this case. It's quick, comprehensible to the non-technical and over several estimates should average out to something approaching accuracy. Especially if OP takes my advice about keeping records of estimates and actuals. When you know what a real-world "Worst case" and "Best case" look like you can feed the actuals into your future estimates and even adjust the estimates for your project manager if the worst case is worse than you thought.

Let's do a worked example:

  • Best case, from experience the fastest I've done a really straightforward one was a week start to finish (5 days)
  • Worst case, from experience, there was that time that there were links everywhere and it ended up taking me 6 weeks (30 days)
  • Actual Estimate, it'll probably take me 2 weeks (10 days)

5+30+2x10 = 55

55/4 = 13.75 which is what you tell your PM. Maybe you round up to 14 days. Over time, (e.g. ten tasks), it should average out.

Don't be afraid to adjust the formula . Maybe half the tasks end up nightmares and only ten percent are easy; so you make the estmate a/10 + b/2 + 2c/5. Learn from your experience.

Note, I am not making any assumptions about the quality of the PM. A bad PM will give a short estimate to the project board to get approval and then bully the project team to try and reach the unrealistic deadline they've committed to. The only defense is to keep a record so you can be seen giving your estimates and getting close to them.

  • 31
    "They are a fool - but I've met some like that". Indeed. – Kramii Feb 13 '17 at 9:39
  • 17
    I want to upvote this, but I can't get behind a single point estimate. – RubberDuck Feb 13 '17 at 14:59
  • 6
    Ok. +1 for your last bullet point. – RubberDuck Feb 13 '17 at 15:00
  • 5
    +1, an estimate is not an exact time and so it can't be a single number. It also might be worth adding that it is an estimate, not a commitment, so the manager should not expect you to definitely be done. It is a software engineer's responsibility to make the difference clear to their manager. – Kat Feb 13 '17 at 20:14
  • 10
    @mcottle FYI this is not a Monte Carlo estimate. You've simply calculated the expected value (which would only be successful around 50% of the time) of a PERT distribution. Monte Carlo refers to a process where statistical values are derived essentially through brute force with a random number generator. – David Meister Feb 14 '17 at 8:54
30

This might be a good moment to introduce a quasi-agile approach. If instead of estimating in terms of hours/days you allocated a fibonacci type scale & gave each task a value based on how big it is:

  • 0 - instant
  • 0.5 - quick win
  • 1 - simple change
  • 2 - a couple of simple changes
  • 3 - more challenging
  • 5 - will require some thinking about
  • 8 - a significant amount of work
  • 13 - a big chunk of work that probably needs to be broken down
  • 20 - a massive chunk of work that definitely needs to be broken down

Then once you estimated a bunch of tasks like this you work on them. In an agile environment you develop 'velocity' which is a measure of how many points you achieve in, say, a week. Once you've done a few weeks of test-and-learn (you can sell this to your manager as part of the process - "I'll need a few weeks of test & learn to understand the estimation process") you will be more confident in how many points you can push through each week & therefore you can translate your points estimate more readily into time.

https://pm.stackexchange.com/questions/4251/why-would-teams-use-the-fibonacci-sequence-for-story-points

https://stackoverflow.com/questions/9362286/why-is-the-fibonacci-series-used-in-agile-planning-poker

This isn't truly agile as it wouldn't involve the ceremonies but I get the idea from the OP that he is on his own. Hopefully this approach might give some more confident estimates.

  • This works best on bigger scale projects (more than a month). On smaller scale projects, this could only work after a few similar projects. – Emile Bergeron Feb 14 '17 at 20:31
  • 1
    @RobP. it's a quirk in agile story point progression: 13, 20, 40, 100 - though most people don't bother setting more than 20 points as by then you really do need to break it down – HorusKol Feb 15 '17 at 3:47
  • 1
    I disagree agree that story points + ceremonies = Agile. – webdevduck Feb 15 '17 at 9:19
  • 1
    @webdevduck "disagree agree"? – krillgar Feb 15 '17 at 14:00
  • 1
    @krillgar D'oh! Disagree! – webdevduck Feb 15 '17 at 14:35
14

The first thing you do is start gathering data on how long it takes you to get anything done right now. The more data you have on your team's performance, the better. It's going to be all over the board, but don't worry about that right now. It's the truth and you need to show your boss reality.

Then you're going to go buy a few books.

  1. Software Estimation: Demystifying the Black Art by Steve McConnell
  2. Working Effectively with Legacy Code by Michael Feathers

McConnell's book is going to tell you to start gathering data and then explain how to use it to get more accurate estimates. Always give a 3 point estimate! Always. Be sure to highlight the parts of the book that talks about how poor code quality will blow your estimates. Show them to your boss.

Explain that if accurate estimates are important to the company, you'll need to start applying the things you're learning from Feather's book. If you want to go quickly, smoothly, and predictably, you'll need to start refactoring the code and get it into a test harness. I've been right where you are. Development time is completely unpredictable because you have no idea what you could possibly break, right?... Yeah. Get it into a test harness. A CI server to run those tests couldn't hurt either.

Lastly, explain to your boss that things are still going to be a bit unpredictable for a while. Likely a few years, but that development will become easier daily and estimates will become more accurate as you have more data and the code gets better. This is a long term investment for the company. I went through this recently, it took nearly 2 years to become mostly predictable.

I know I talked more about improving the code than estimating, but the hard truth is that your estimates will be lousy until you can tame the legacy code base. In the mean time, use historic performance to gauge how long it will take. As time passes, you'll want to take into account whether or not you've already gotten the code up to spec in your estimates.

  • 1
    +1 for "get it into a test harness." When refactoring old code, a test-first approach (to verify the critical components of the old code work exactly as you think they do before you change anything) is unbeatable. This answer also convinced me to purchase the "Software Estimation" book which I had never heard of before (my estimates are poor). – GlenPeterson Feb 13 '17 at 15:30
7

Now my boss is rightly asking me an estimation on how long would it take to write feature X in the new architecture. But I'm having difficulties coming up with a realistic estimation; often times I way underestimate the task due to reasons I've stated above and embarrass myself because I can't finish in time.

You are perhaps thinking in the box of submitting one estimation. I have to work in legacy code, and when I make a more formal estimate, I usually make two or three:

  1. Primary Estimate - assuming that I have to spend some time digging but the architecture allows the changes we want
  2. Angelic Estimate - assumes that everything is transparent/easy-to-find and I only have to make minor changes (this is the one I leave out sometimes... especially if I know there are only devils in a particular code base)
  3. Abyssal Estimate - assumes that the fundamental structure of the legacy code is incompatible with the requested feature and I'll have do major refactoring to make things work

All three estimates take into account how tough the feature is in and of itself, any experience I've had with that general code base, and my gut feeling about the change (which I've found can be quite accurate)

After these estimates come out, I keep my manager up-to-date on which one it looks like we're dealing with. If it turns out we're looking at an abyssal feature, then we may have to sacrifice it - it's happened. If your boss can't accept that there are abyssal features for a given chunk of legacy code, then I wish them good luck, for they will have a very difficult and frustrating life.

  • +1 for the last paragraph - I wish I'd included that in my answer – mcottle Feb 14 '17 at 2:31
3

When I have faced this sort of problem, I have relied on giving ranges on my estimates. I have gotten away with telling my bosses "it is hard to do good off-the-cuff estimates on this codebase. If you ask for one, it will be a very wide estimate." I've given "3 days to 3 years" as an estimate once. Needless to say it wasn't a popular estimate, but it's what I gave.

The key to this is an agreement that I will update my estimates as work progresses. So if I get told "Implement XYZ, how long will it take?" my answer might be "somewhere between a day and 4 months. However, if you let me actually look at the code for a few hours, I can reduce the uncertainty in that window." I then go look at the code and come back with "2 to 4 weeks." That's still not an ideal window, but at least it's something that can be managed.

There are a few keys to this:

  • Convince the boss that these estimates are better treated as a conversation because you will learn more about what the task looks like while you work it. This is an opportunity for your boss to have information they would not have if they just asked for a single estimate.
  • Offer options as to how to go forward which trade code development speed vs. improving estimates. Give them an extra knob they can turn. Sometimes the bosses know a task just needs to get done, and they only need a ballpark estimate. Other times they're running the pros and cons of a task, and the ability to refine the estimates is valuable.
  • If possible, I'll also offer synergy bonuses. Often there's architectural improvements that would have benefits to many tasks. If I have 10 tasks all of which take "1-2 months now, but would take 2 weeks with upgrade X," it's easier to sell the 20 weeks it might take for upgrade X.

If I have a boss who is not comfortable with receiving a range that is updated as I go, I'll give them a single number and my methodology. My methodology is a combination of a rule of thumb I have been told as a young developer, and Hofstader's law.

Estimate how long you think the task should take, then quadruple that number and give that as your estimate.

and

Hofstadter's Law: "It always takes longer than you expect, even when you take into account Hofstadter's Law."

2

The sensible thing might seem to really get into the code, note every branch and calls to other functions and then estimate the time cost. But there is really a minuscule difference between documenting the old code and actually writing down the new version.

This is the solution to your problem. You cannot estimate if you have no requirements. Tell your boss you will need to do this before you can start coding. After a few functions and modules, you may discover they've all been consistently coded (in this case poorly), so you have a baseline to determine future estimates. Just make sure you adjust your estimate if you discover the coding gets worse.

I realize your boss wants an estimate, but without knowing how this information is being used, we don't know how exact your estimates need to be. Have a conversation with him and find out. If he just needs a number to give his boss, you can inflate the estimates slightly and provide a number. For clients waiting to pay for your code until this is done, make sure you find out if hard line due dates are going to drive significant revenue.

  • Even though a deep understanding is necessary to understand the old code, there is a vast difference between documenting old code, and getting newly written code to the point where it has no bugs. – Thorbjørn Ravn Andersen Feb 14 '17 at 21:54
1

In a situation like this I do not believe it's possible to give good estimates. The basic problem is that often a big part of doing it is figuring out exactly what needs doing.

I handle cases like this by giving an estimate based on what it appears to entail but with the cavet that surprises are likely. While I have not had to deal with much in the way of legacy code I have had some very nasty surprises dealing with input--I've seen a few hours turn into a couple of weeks and once into this-is-impossible (After considerable digging I figured out I didn't have enough data in a certain case, back to the drawing board.) Fortunately, my boss understands when I give such estimates.

-1

Well, estimation is a skill some people never learn well. It does not make you useless as a developer though even if you cannot come up with good estimations. Maybe team mates or management will fill in the gaps. I am terrible at it, still most teams liked to work with me. Keep calm, team up and carry on refactoring.

Technical debt gives you nice little challenges, but remember that a company/team that ended up producing debt will continue producing debt unless there are changes to the team spirit or the management. The code is just mirroring the social problems, so focus on the real issues.

We used a heuristics for estimating features in a brownfield project: We estimated how long it would have been to implement that feature in a greenfield project without anything already implemented. Then we multiplied that estimation by 2 to deal with cleaning up debris that already existed.

This factor depends on the amount of coupling and the overall code size, but if you do some features this way, you can interpolate that factor based on actual evidence.

-3

I think you should sit down with your boss, look him directly in the eye and say:

'Listen boss! We are just refactoring here. There is no new functionality to deliver, and no customers waiting for that functionality; so there shouldnt be any deadlines. This is going to take as long as it takes, you need to decide whether we have to do it or not.'

Use firm assertive gesticulation like pointing and sit forward in your chair.

Alternatively you could make up some numbers to make him happy. But lets face it, until you are half way through the job your estimates are going to be pretty inaccurate.

  • 3
    -1 for recommending what is potentially career suicide. Also, OP says he's estimating feature work, not just refactoring the existing code. – RubberDuck Feb 13 '17 at 11:07
  • career suicide OR making the leap to the big game – Ewan Feb 13 '17 at 14:25
  • Well, that's a fair point @Ewan. I can't say I haven't done a few things that seemed like career suicide in the moment. – RubberDuck Feb 13 '17 at 14:56
  • Some things can't be estimated. Communicating that can be frustrating. That said, I voted this question down because it reads like you are suggesting the OP try to intimidate their boss into believing them. I know that happens, and maybe it's even necessary in an isolated desperate situation. But I don't want to work anywhere that's the norm. We have disagreements at work and get upset. But we deal with it by trying to convince each other with data, studies, and stories. A company is more likely to succeed with a culture of "the best idea wins" than "the most intimidating person wins." – GlenPeterson Feb 13 '17 at 22:12
  • 1
    its a tongue in cheek answer. but I mean it in a serious way. why is the boss asking for estimates? are you helping the situation by estimating? its all very well this 'read uncle bob' 'use the Fibonacci sequence' style answers. but they dont get to the root of the problem. the boss is worried that this refactoring is a waste of time and wants it to be over soon – Ewan Feb 13 '17 at 23:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.