Recently, I received this nice reply on Twitter:
There's some technique to my productivity and I'd like to try to describe it in this post. It's mostly focused around minimizing idle time and easing context switching. In turn it allows me to have high output and visibility while keeping work-life balance in harmony.
What this is not: A prescriptive, "10 tricks to improve your productivity" guide. It works for me, it definitely won't work for everyone.
(in no particular order)
Keep multiple clones of the main project. At any given point I'll have 3-5 branches going and it's nice to be able to put something down without soft-resetting my workspace. Sure, you can
git stash or
git commit -am "WIP", but still requires changing branches and re-syncing the IDE. Sometimes I even have multiple open at once.
Minimize builds. If I can make a change without needing to build it, great! Dependency updates, simple refactorings, etc can all be committed and left to CI to build. Similarly - work in small well-isolated projects that build quickly and without much of a dependency dragnet. This is an excellent incentive to modularize.
Don't wait for CI. CI will take its time and there's no real benefit to watching the console log or sitting idly while I wait. I have GitHub reminders set up with matchers for our common CI jobs so it will ping me on Slack if there's a failure. In the meantime, I'll switch to working on something else (more coding, code review, etc). If you maintain multiple clones like mentioned above, you can easily jump back in to fix small issues CI reports too without doing a whole context switch.
Work on multiple things. Only 1-2 larger things, but I track a lot of small work I can pick up in idle moments. Dependency updates, small bugs/improvements, etc. I always feel like I have something I could do and as a result I don't feel limited by smaller gaps of time. This is where a lot of my OSS work happens too, as those aren't usually large scale tasks.
Get it working first. Then optimize from there. Until I have a working (test) case, I have no idea if my changes work and likely to run in the wrong direction for too long. The first iteration of any solution is usually the stuff of technical interviewer nightmares. But it works!
Use magic cursors, replace in path, and structural replace. I use these all the time and they are refactoring superpowers. They're also exceptionally useful for hand-processing bulk data rather than trying to script it. Low effort, high reward.
Script migrations. Basic Kotlin scripting can do a lot of work in migrations for you. Not necessarily kscript even, just a simple scratch file or
fun main() implementation usually suffices. It doesn't have to be precise, just enough to do most of the grunt work and let a human come through and clean up the rest. Low effort, high reward.
Don't keep thoughts in ephemeral places. This includes in my head. If I'm so far down the rabbit hole in a thought that I'm worried about losing it all with an interruption, I'm too deep. I can barely remember names, why would I try to keep complex logic in there? Scribble things into comments and notes quickly and often. You know what's a super dumb but super simple way to remember a relevant line of code? I set a breakpoint on it. Not because I'm going to hit it in the debugger, but rather just because that highlight's a reminder for me later. I have to leave breadcrumbs because otherwise I will absolutely forget it.
Put things down. This might feel obvious, but if I'm at a dead end on something then I'll just put it down for a bit. No reason to idle on something that's not clicking. The human mind operates on parallel tracks and even when something's on the back-burner, some part of your head'll still ponder it and come up with something later. If I'm on a time crunch and can't put it down for a few hours or a day, rubber duck debugging with a coworker for a few minutes is immensely helpful too.
Leave breadcrumbs. Related to the above two, but if I'm getting pulled away from something I was in the middle of then leaving a short note or few comments allows me to switch back on to it when I return. For me, this completely mitigates just about any interruption I get throughout the day.
Sleep is the best debugger. If I'm really stuck on something or not sure how to go about it, sleeping on it is the best tool.
Embrace the gaps. Not everyone can context-switch easily, but I 100% believe it's a skill that can be practiced and a lot of it is down to mentality. If I react to every interaction like it's ruined my day, every interruption is going to ruin my day. If I've comments/notes/breadcrumbs, I can easily pick up where I left off.
While not principles really, these are some other relevant details of how I work:
- I work sort of when I feel like it. It's an extremely privileged position to be in and far from normal for work. I'm online during core hours obviously, but that's only really ~12-5pm my (NYC) time as most of my team is on the west coast. ~10hrs/week are when I feel like it, be it a few hours on the weekend or an hour after dinner.
- Some weeks I work way less than 40hrs. Some weeks I work way more. It's not for everyone, but right now it works well for me. If I worked a strict 9-5 right now, I would burn out. I'm equally fortunate that my team/company don't really care how I get my work done as long as I get it done. I'm still young-ish without many life responsibilities outside of work, so I'm gonna make the most of it while I can!
- I worked hard on working in bursts starting a few years ago. Train commutes or air travel were particularly good times with 15-45 minute gaps I could just jump into something. I wrote most of CatchUp this way. Being intentional about this makes a big difference in mindset about the limited time and I gradually reduced the minimum unit of time needed to feel productive.
- Meeting schedule: at the time of writing, I have 16 meetings on my calendar this upcoming week. 9-10 actually require my attendance and 4-5 of them are social. Not too heavy, not empty either.
- Doing small things that unblock other folks are a great way to build social capital. Whether that's doing a dependency update to pick up a fix, quick code review on the go, or answering a quick question to save them a lot of time searching. Low effort, high reward. My time is precious, but not so precious that I can't take a minute to help a coworker get ahead.
- I legitimately love what I do. I enjoy programming in my free time and I enjoy doing it for work. It is, in many ways, a meditative practice for me, like building legos or solving puzzles. This is, again, an extremely privileged position to be in and something that makes much of the above easier.
- I actually strongly dislike working from home (sorry, tech Twitter) because it makes me feel like I'm living at work. That's just me though! With us having no offices in NYC right now (let alone open ones), I spend most days working outside a local coffee shop. Working in bursts and avoiding builds locally is seriously helpful for preserving battery on the go like this. I actually work on a 13" MacBook Pro these days (portability!), which also benefits from small/avoided builds.
Some people are watchmakers, meticulously working on exactly one thing for days or weeks at a time until it's perfect. I am not a watchmaker. I'm more like a chef, preparing a number of dishes at once. Some are big, some are small, some are on the back burner, some are maybe boiling over. Sometimes all the burners are on and sometimes I'm not in the kitchen.
Everyone's different, but this works well for me. I hope this is at least interesting for some and maybe even helpful for others. Please don't take it as gospel or anything resembling blanket advice though! Do what works best for you, try different things, identify what slows you down, and try to improve it.
Thanks to Cli for proofreading this!