Software engineering is more than just coding. I hear a lot of questions from early-career engineers about what exactly constitues “work”, and how they’re expected to spend their time. They might say things like:
“I feel like I didn’t get anything done today. I didn’t write any code, I just did a lot of project planning.”
“I spent a lot of time today investigating this bug, but I don’t know if I should’ve spent that much time on it.”
“I’m not sure what my mentor does. They spend a lot of time in meetings, and it doesn’t seem like they commit much code. What are all those meetings about, anyway?”
“My manager says I’m not really a senior engineer yet, but I don’t know what that means.”
This last one might seem unrelated, but I think there’s actually an interesting connection there. Let’s talk about the differences between straightforward, difficult, and exploratory work, and who is expected to do which kinds of work.
Straightforward work is work where it’s obvious to the team what needs to be solved and how it should be done. This is often repetitive; there may be examples of very similar work that can be copied, and the systems involved are probably well documented.
Difficult work requires a deeper understanding of the systems involved. It may involve undocumented, unusual, or subtly complicated systems. Perhaps it’s a frustratingly elusive bug that needs to be understood and fixed. Or, it may involve implementing a change that doesn’t feel natural given the existing structure of the code. The team is probably clear on what needs to be solved, but it won’t be obvious how to solve it.
Both of the first two are types of implementation work. In both cases, the team agrees on what needs to be solved.
Exploratory work is a little different. It’s about framing problems and figuring out what should be done. Initially, both the how and the what are unknown; usually you start with a question, or a problem, and see where it takes you. You might start with something like:
“It seems like it takes us a long time to write new features. What’s slowing us down?”
“This system has a lot of bugs and is pretty fragile; it’s making our oncall rotations a nightmare. What should we do about it?”
“The product team wants us to build this new feature, but none of the engineers have worked on this kind of thing before. We need to do some research to figure out what kinds of approaches make sense.”
Exploratory work can be extremely impactful - a good recommendation here might save your team weeks, months, or years of wasted effort. It’s also easy to bullshit, because it’s difficult to measure or assess. In order to do this effectively, you generally need deep context on the systems involved as well as your team’s priorities. Figuring out how to solve the problem might be out of scope entirely - the goal here is to define what the problem should be.
I expect successful junior engineers to be able to do straightforward work (#1). Midlevel engineers should be able to tackle difficult work (#2). Senior and staff engineers will be able to do exploratory work (#3).
(There are other aspects that separate junior/midlevel/senior engineers - for instance, can you work alone? Collaboratively? Can you teach new engineers? Can you lead teams? Can you propose new projects and get buy-in for them? Do you follow through and clean up after yourself? But I’m going to set those aside for now.)
Depending on your company and your team, the mix of work required will vary wildly between 1/2/3. Some teams will have mostly #1, with some #2, and therefore even the senior engineers will spend most of their time writing code and implementing straightforward projects. My current team is probably a balance of mostly #2 and #3. (The larger/older/more complicated the codebase, the more likely you are to have #2 or #3 work.)
Exploratory work can overlap strongly with glue work, as described by Tanya Reilly.
Much like with glue work, there’s a risk of doing too much exploratory, “problem-framing” early on in your career. It can take a lot of time and not produce a lot of measurable (i.e. promotable) artifacts. Also, your judgment simply won’t be as good, if you haven’t done enough implementation work in your team’s current domain. Often, it’s the pain points encountered while doing implementation work that lead to obvious questions to explore.
Doing exploratory work rarely helps support a promotion from junior to midlevel engineer, because exploratory work is largely irrelevant to the qualifications of a midlevel engineer. Most companies seem to define midlevel as “can this person accomplish tasks independently, within a reasonable amount of time, with minimal direction?” By contrast, a “senior” engineer is usually roughly defined as “can this person figure out what we should be doing, and make a good argument for it, and implement it?”
The division between senior and staff is even fuzzier, and depends a lot on what company you work for. As a staff engineer at a large-ish tech company, right now my job consists almost entirely of doing two things. First, I advise other engineers on how to approach implementation tasks, though I don’t usually do implementation myself. This includes a bunch of assorted feedback, mentorship, design review, code review, and brainstorming sessions. Secondly, I do exploratory work for issues that affect multiple teams.
This means I spend a lot of time learning more about problem domains; learning about individual team’s needs / priorities / motivations; learning about the history of different aspects of the company; and then, finally, synthesizing that into a sufficiently reasonable plan of action and convincing people that my approach makes sense. Sometimes, I do all of this research, only for my recommendation to be “do nothing, for now, for these reasons”. This is weird work! The hardest parts are often invisible, and difficult to verify. It often takes many months, or even years, to evaluate if I’ve done my job well.
The somewhat surprising takeaway here is that senior engineering work includes a lot of stuff that doesn’t naturally produce concrete artifacts…but that doesn’t mean it’s unimportant. Exploratory work is real work, too. That doesn’t always mean it’s the best use of your time (implementation has to happen eventually, right?), but don’t discount it as a valuable pursuit.