This article first appeared on the Triplebyte blog and was written by Joseph Pacheco. Joseph is a software engineer who has conducted over 1,400 technical interviews for everything from back-end, to mobile, to low-level systems, and beyond. He’s seen every quirk, hiccup, and one-of-a-kind strength you can think of and wants to share what he’s learned to help engineers grow.
Changing the way you manage your time is one of the biggest challenges when you start working remotely as a software engineer. When you're in an office, things have a way of working themselves out. When you're distributed, it's a whole different ball game.
You see, onsite work is to remote work as synchronous programming is to asynchronous programming. If you're used to the former, the latter requires a paradigm shift in the way you think about the basics.
But once you make the transition, your day goes from reactive chaos to predictable smooth sailing. Here’s what you need to know.
Think about what it's like to be in an office. Not only is everyone occupying the same physical space, but they are also sharing, for the most part, the same working hours. This is something most of us take for granted because we've never known anything else. And it has a bunch of nifty advantages — which we also take for granted.
For example, if you run into a problem while coding, there's nothing stopping you from popping over to someone's desk to get questions answered. You don't need to wait on Slack wondering if they saw your message, and you can physically see whether it's an appropriate enough time to politely interrupt for a quick question.
When you're remote, you simply cannot rely on such conveniences. You have no control over when your co-workers see your messages or choose to respond, and you usually don't have fail-safe ways of getting their attention. You have to proactively plan ahead for situations so your productivity doesn't get derailed when you're blocked. Software doesn't stop running when it's waiting on some thread to complete, and neither should you.
One of the most important techniques you have at your disposal is what I call "strategic multi-threading" (SMT). It's multi-threading because it involves multiple streams of work done in parallel (just like modern computer architecture), and it's strategic because it takes into account the limitations of the human mind.
That is, computers can task-switch arbitrarily without loss of productivity. Humans cannot. Every time a human task-switches, there is significant cost of mental energy and time to ramp up and down. So we need to be thoughtful about how and when we do it. Here's the process:
When you find yourself blocked, give yourself a reasonable amount of time to get unblocked. Task-switching is mentally taxing enough that you should give yourself at least half an hour before attempting to focus on anything else. You don't want to be waiting hours-on-end doing nothing, but you also don't want to spend energy starting something only to have your original problem resolved ten minutes later. It's ok to take a breather, and it's better for your productivity and the company. Contact who you need. Be resourceful about how else you might be able to get your questions answered sooner than later. Then relax and wait.
After half-an-hour, re-evaluate your situation and consider other tasks based on your circumstances. You should always keep a backlog or menu of light-weight things you can do that add business value but don't require deep thinking (and therefore high task-switching cost). Respond to emails, update your tickets on JIRA, get unrelated questions answered, make notes for tomorrow's standup, etc. If a co-worker said they'll be available in an hour, do a number of these lightweight tasks that are appropriate for an hour. If no one has responded, just start ticking off some items and re-evaluate again in an hour's time (or whatever makes sense based on the data you have).
If at some point it starts to seem like you might be waiting a few hours (or days) to get unblocked, it's time to dive into something more substantial. You may want to switch branches and work on some bugs. Perhaps there's a ticket that is smaller in scope than the rest. Ideally, you should choose something that you have a decent chance of finishing before you have to switch back to the original task you were focusing on. Deadlines are deadlines, so you will have to use your judgement. But if you can get away with finishing the new task before you switch back to the original one (even if you get unblocked before you're finished), then that's worth doing. And even if you only have large, sprawling tickets on your backlog, choose something that can be broken into smaller parts and complete one of those components. The idea is to reduce task-switching as much as you can while negotiating with the realities of your particular circumstances.
SMT is great when you need it, but ideally you'd like to avoid task-switching as much as you can. One way of doing so is taking a little time to think about blockers before they arise. You can't plan for everything, and you certainly don't want to burn time chasing a hyperbolic number of imaginary problems. But you'd be surprised how useful a short pre-gander at your tickets can be.
That is, at the start of each sprint, take an hour or two to go through all of your assigned tickets. For each, do some light thinking. Read through the requirements to see if anything stands out as unclear or ambiguous. Think a smidge about how you might approach the task, so the more obvious problems present themselves. Your goal is not to avoid 100% of blockers, it's to quickly gather the low-hanging fruit.
As you go, write down any questions that come to mind. Then fire them off to all parties involved. Often, by the time you start a ticket, you'll have your answers so you can work with minimal interruption to your flow. Race condition avoided!
Pre-thinking is just one way to identify blockers before they are a problem. The way you communicate to your team during check-ins and meetings can also be invaluable.
For example, let's say you're working on some feature, and it's time for daily standup. Of course, be sure to include what you accomplished yesterday and what you plan to accomplish today. But it would also be valuable to state any assumptions you're making as you implement the feature. Perhaps you'd like to clarify the way you're interpreting one of the requirements so the product team has an opportunity to voice any objections. You may also want to state your assumptions about other technical components or APIs you're using, so other members of the engineering team can offer clarification if needed.
The idea is not to rattle off every detail you can think of. The idea is to be thoughtful of details relevant to other co-workers in a given meeting. The meeting is a shared space for collaborative thinking. If you share the most relevant details in your head, it will trigger others to contribute additional relevant details which will avoid blockers in the future.
Adapting to the asynchronous nature of working remotely is just one piece of the puzzle when it comes to managing your time effectively. There is also the problem of going from an office (which subtly structures your entire day for you) to an environment with no social cues and vastly more autonomy over your time. Stay tuned to the “wfh://engineering” series on Triplebtye for tips on that and more!
Triplebyte helps engineers assess and showcase their technical skills and connects them with great opportunities. You can get started here.