One of the lessons from Joel Spolsky I took to heart right from the start of my career as a software developer was to schedule tasks honestly. Scheduling dishonestly means estimating a task when you don't really know what work is involved. As a result, you end up putting an incorrect time estimate on it.
To combat this, you should schedule honestly and Joel proposes this simple rule: tasks should be measured in hours not days, with a realistic estimate being no larger than 16 hours. If your estimate is larger than that, then you probably don't appreciate the true size of the task. Experience tells us that programmers usually underestimate tasks they don't fully understand, so estimating in terms of days or weeks risks schedule overrun. Tasks which will take more than a day or two should therefore be broken down into smaller sub-tasks, because this forces you to think about the work in more detail and gain a better understanding of it.
But how much time is in a day?
So an 8-hour task will take about a day, yes? Well, maybe not. One of the other things I recall Joel saying is that there is less time in the day than you think. Yes, we 'lose' time to lunch breaks and meetings, but that's quite easily taken account of in a schedule.
What about that other 'lost time'? You know what I'm talking about: all that web-surfing, checking email, chatting at the water-cooler. How much time every day is 'lost' to these? And how guilty do they make us feel when work ends, because we know we spent a cumulative hour on them instead of completing that task which should have taken only a day.
In actuality, we probably shouldn't be feeling guilty about this at all. We should just be scheduling better.
Scheduling in cycles
I recently read this article: "The origin of the 8 hour work day and why we should rethink it". It presents interesting arguments for switching away from a traditional 8-hour work day and has several tips for working more effectively. The one that really intrigued me was the argument that human concentration follows a natural rhythm whereby we can focus on a task for a certain amount of time before we start to lose it and need a break. The article claims that most of us can hold focus for about 90 minutes before requiring a break of around 20 minutes, and so advocates planning work time in 90-minute windows (let's call them cycles).
So what happens when we combine this with Joel's advice? A task estimated to take 6 hours effort (360 minutes) would require 4 cycles (4 x 90 minutes). When you factor in the 20-minute breaks between tasks that's an extra hour.
If you can manage more than four cycles in a day then good for you, but four is enough for me. Under this cycle-scheduling system then, "one day" (if we stick to an 8-hour day) clearly gives you six hours work time, a one-hour mealtime, and recognises that we all give in to the temptation to take little breaks now and again.
Can it work for programmers?
Let's consider a few things.
- It factors in those more unpredictable distractions (Facebook, email, coffee etc.) which are actually symptoms of us reaching a loss of focus. Using cycles allow you to actually allocate time for them, which recognises we need them and stops us from feeling any guilt about 'wasting' time.
- It can be encouraging to know that your current cycle of work will soon be followed by a scheduled break, especially when the work is intense.
- You can more easily track the work you did. At the end a day, can I really be sure I put in X hours of work? How much cumulative time was lost to those little breaks? If you follow the cycles, you have more confidence in how much time you really spent on tasks.
- Granularity. Most of the time, programmers can't measure progress with the granularity of certain other professions (like a bricklayer who can measure bricks laid per hour). But there are still activities we can plan which fit into a 90-minute cycle. Think along the lines of: layout one basic screen design, implement that setter function, write the code that makes TestX pass. And speaking of testing...
- Cycles can also help to make the distinction between coding and testing clearer. When you estimate a task as 8 hours, it's easier and tempting to lump the two together in a schedule only to find that coding takes up all the allocated time and testing gets pushed back or even dropped. Using 90-minute cycles encourages the approach of spending one cycle getting something working and then spending the following cycle reviewing and testing what you've done. Most programmers can relate to how different code looks when it's examined again after a break and how this makes the flaws easier to find.
- Interrupting the flow. One objection I've heard goes along the line of: "It can take programmers several hours just to get into a task, so you shouldn't interrupt the flow." This is true, but getting into a task still needs factoring into a schedule somehow. Just like cycles force you to think about the actual small details of a task, they also force you to plan your research or preparation.
- Try reducing the breaks in-between preparation cycles to 5 minutes.
- Be more detailed about what "getting into a task" means: How many pages of a resource can you read in one cycle? How much of a prototype/test code can you write in one cycle? etc.
So, instead of estimating a task or feature in terms of the number of hours it will take, why not in terms of the number of cycles instead? Personally, I like the approach and I already work in a similar pattern anyway. If it is indeed effective and quite natural to all of us then why not make scheduling explicitly take it all into account and give yourself a more accurate project plan?
Edit: One reader seems to have the impression that I'm saying non-peak time is exclusively time to slack off, even though I never stated such a thing and even included work tasks in the examples of non-peak time. Let me make it clear: non-peak time includes unscheduled stuff that doesn't contribute to the development project you're working on and billing for. It could be slacking off time, but it could also be reading your email, checking in with work colleagues, looking at or updating the project plan, and so on.... anything that takes your focus away from the scheduled development work.