Developer Productivity: Systems That Survive a Bad Week
Practical productivity practices for engineers — protecting deep work, reducing context switches, and automating the decisions that do not deserve thought.
Table of contents
- Protect contiguous time, not total time
- Automate decisions, not just tasks
- Make the feedback loop short
- Reduce the cost of remembering
- Debug systematically rather than by intuition
- Know when to stop
- Frequently asked questions
- Do productivity tools matter?
- How do I handle interruptions I cannot refuse?
- Is pair programming productive?
- How much time should go on tooling?
- Related reading
- References
Productivity advice for developers usually optimises typing speed. The actual constraints are attention, context and decisions — and each has a systemic fix.
Protect contiguous time, not total time#
Writing code requires holding a model of the system in your head. Rebuilding that model after an interruption takes real time, and there is good evidence it is on the order of tens of minutes for complex work.
The practical consequence: four one-hour blocks are not equivalent to one four-hour block. What helps:
- Block calendar time and treat it as a meeting. An unprotected calendar gets filled.
- Batch communication. Two or three deliberate check-ins beat continuous partial attention. Notifications off during a block.
- Write down where you are before stopping. A two-line note ("next: fix the off-by-one in
nextRuns, then wire the timezone option") makes resuming cheap. This is the highest-return habit on this list.
Automate decisions, not just tasks#
Every trivial decision consumes attention. Remove the decision rather than making it faster:
- Formatting. Prettier on save, with the config committed. Nobody discusses quote style again.
- Linting. ESLint with
--fixon save. The rule is the decision, made once. - Commit hooks. Format and lint staged files before the commit exists, so CI never fails on style.
- Conventional dependencies. One state-management choice, one date library, one test runner. A codebase with three ways to do the same thing taxes every reader.
The measure of a good default is that it is invisible.
Make the feedback loop short#
The cost of a change is dominated by how long it takes to know whether it worked.
- Hot reload for UI. Non-negotiable.
- Watch-mode tests scoped to the file you are editing. A full suite on every save trains you to ignore it.
- A typecheck that runs in seconds. If
tsctakes two minutes, you will stop running it and find out in CI instead. - Fast CI. Under two minutes gets checked; eight minutes gets ignored. Cache aggressively and cancel superseded runs.
If a loop is slow, fixing the loop usually returns more than any amount of discipline.
Reduce the cost of remembering#
Your memory is not the right storage medium for project state:
- A written decision log. One paragraph per non-obvious decision, in the repo. "Why is this a native
<select>and not a Radix one?" should have a written answer, not an oral tradition. - Comments that explain why, not what. The code says what. A comment earns its place when it records a constraint, a measurement, or a rejected alternative.
- A README that gets someone running in under five minutes. If setup requires asking a colleague, it is broken.
Debug systematically rather than by intuition#
The fastest debugging is not clever, it is methodical:
- Reproduce it reliably. An intermittent bug is not yet a bug you can fix.
- Read the actual error. All of it, including the stack trace. This step is skipped astonishingly often.
- Bisect. Comment out half.
git bisectfor a regression. Binary search beats reading. - Check your assumptions. Log the value rather than assuming what it is. Most bugs live in the gap between what you believe and what is true.
- Change one thing at a time. Two simultaneous changes make the result uninterpretable.
Know when to stop#
Two failure modes worth naming:
Gold-plating. Adding abstraction for requirements that do not exist. The cost is paid by every future reader.
Sunk-cost debugging. Three hours into an approach that is not working, the right move is often to delete it and start differently. Setting a timebox before you start makes that decision easier, because you decided it when you were not invested.
Frequently asked questions#
Do productivity tools matter?#
Marginally. The editor and terminal you know well beat the ones you have just installed. Switching tools is usually procrastination in a productive costume.
How do I handle interruptions I cannot refuse?#
Write the two-line resume note before you switch. It converts a 20-minute recovery into a 2-minute one.
Is pair programming productive?#
For genuinely hard problems and for knowledge transfer, yes. For routine work it costs two people's time for one person's output. Use it deliberately rather than by default.
How much time should go on tooling?#
Enough that the loop is fast, then stop. A day spent making CI three times faster pays back permanently; a week spent on a bespoke build system rarely does.