As a software engineer, one thing that I've never connected with is the idea that engineers only have "N" number of hours per day in which they can be productive. I believe this concept stems from a lack of strategy, not a lack of capacity. I am not going to argue that every hour of every day has equal potential; but, I do think that we can employ strategies to maximize every hour if we learn to lean into the constraints of our day instead of fighting them.
If you're like me, you can eat a massive dinner and still have room for a dessert (or two). This isn't just gluttony, it's a phenomenon known as sensory specific satiety. It means that part of the sensation of being full (sated) is directly tied to the food being eaten. Which means that when you switch the food you are currently eating, your sensory perceptions reset, you no longer feel full, and you can continue to eat.
I apply this same concept at work. But instead of switching foods, I'm switching tasks. Once my brain feels "full" on a given task, and I know that I can no longer remain productive on said task, I switch it up. This usually means changing from a high-thinking, longer-term task over to a low(er)-thinking, shorter-term task. My brain resets, the feelings of task satiety dissipate, and I'm ready to rock once again.
On top of the mechanics of "task satiety", I also lean into the fact that I am more creative in the early part of the day. As such, I do more creative work - like architectural and user interface (UI) design - in the morning. And then, in the afternoon, I skew more heavily towards implementation details and bug-fixes.
By embracing the idea that my brain can only be productive on a single task for "N" hours, I can force my brain to remain productive for the entire work day. In fact, on days where I do this most effectively, I can even end the day feeling energized, not depleted. But, again, the trick is to lean into the constraints of your day, not to fight them.
Task Satiety, Task Estimation, and Why I Have to Double My Estimates
Most engineers are terrible at estimating how long it will take to complete a large project. I'm no different; but, understanding "task satiety" helps me estimate work more accurately. Because I know that "one day of work" isn't 8 straight hours of work.
For the sake of discussion, let's say that I can remain productive on a single task for 4-hours before my brain feels "full" and I have to switch tasks. This means that if a task looks like it will take "a day" - or, 8-hours - that's really 4-hours spread-out over two days of effective coding.
What this means is that I have to double my estimates. Because when I think about how long a task will take, I think in terms of contiguous time. But, when I go to implement said task, I can only operate in discontinuous bursts of focused effort.
Having a Backlog of Bugs Can Super-Charge Your Productivity
It's one thing to embrace task satiety and task switching; it's another thing to know what task to switch to. My biggest productivity killer is not having a backlog of things that I'm interested in working on. If I don't know what to work on next, it means that my brain has to work hardest (task selection) at the point it is most "full". This can easily lead me into a pit of despair where I end up checking Twitter instead of solving customer pain-points.
Because of this, I try to always have several tasks standing by in my mental queue. This way, when my brain fills up on one task, I can immediately switch over to another task, reset, and keep on jamming-out in my code editor!