0% found this document useful (0 votes)
272 views

The Software Engineer's Guidebook - Bonus Chapters

The document summarizes the pros and cons of working at a startup versus working in big tech, according to Willem Spruijt's experience. Spruijt has worked at both startups and big tech companies like Uber. Some key points are: at startups you can have a large impact and learn quickly due to wearing many hats, but there is more financial risk and stress; big tech allows specializing in specific areas and has more financial stability through salaries and bonuses, but less direct impact. Overall the document provides insights from someone who has experienced both environments first-hand.

Uploaded by

Anan Lowell
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
272 views

The Software Engineer's Guidebook - Bonus Chapters

The document summarizes the pros and cons of working at a startup versus working in big tech, according to Willem Spruijt's experience. Spruijt has worked at both startups and big tech companies like Uber. Some key points are: at startups you can have a large impact and learn quickly due to wearing many hats, but there is more financial risk and stress; big tech allows specializing in specific areas and has more financial stability through salaries and bonuses, but less direct impact. Overall the document provides insights from someone who has experienced both environments first-hand.

Uploaded by

Anan Lowell
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 103

The Software Engineer’s Guidebook:

Bonus Chapters

The below 10 chapters are complimentary contents for The Software Engineer’s Guidebook.

These chapters are a mix of contents written for the book that did not make it into the nal
edition, and articles that are highly relevant for certain parts of the book, and were rst
published in The Pragmatic Engineer Newsletter.

These 10 bonus chapters are about half the length as regular chapters in the book. The total
length of this bonus section is around 100 pages, and is about a quarter of the length of the
book.

I hope you nd these bonus content useful!

– Gergely

The Software Engineer’s Guidebook: Bonus Chapters Page 1


fi
fi
fi
Table of Contents
Part I: Developer Career Fundamentals 3

Bonus #1: Working at a Startup vs in Big Tech 1

Bonus #2: The Seniority Rollercoaster 6

Part II: The Competent Software Developer 14

Bonus #3: Advice to Myself When Starting Out as a Software Developer 15

Bonus #4: Getting Things Done as a Developer: Exercises 19

Part III: The Well-Rounded Senior Engineer 22

Bonus #6: Executing a Migration: Doing it Well 23

Bonus #7: Getting Things Done as a Senior Engineer: Exercises 43

Part IV: The Pragmatic Tech Lead 45

Bonus #7: Consolidating Technologies 46

Bonus #8: Becoming a Better Writer as a Software Engineer 61

Part V: Role-model Sta and Principal Engineers 76

Bonus #9: Working Well with Product Managers 77

Bonus #10: Ways Sta and Principal Engineers get Stuck (and How to Get Unstuck) 87

Closing 100

Further reading 100

The Software Engineer’s Guidebook: Bonus Chapters Page 2


ff
ff
Part I: Developer Career Fundamentals
The Software Engineer’s Guidebook covers these chapters for this part:

● 1. Career Paths
● 2. Owning Your Career
● 3. Performance Reviews
● 4. Promotions
● 5. Thriving in di erent environments
● 6. Switching jobs

The two bonus chapters:

● Bonus #1: Working at a startup vs in Big Tech


● Bonus #2: The seniority rollercoaster

The Software Engineer’s Guidebook: Bonus Chapters Page 3


ff
Bonus #1: Working at a Startup vs in Big Tech
Willem Spruijt is a software engineer whom I worked on the same team with at Uber in
Amsterdam, building payments systems. We started as teammates, and in a twist, I became
Willem’s manager. He was a very productive engineer at Uber – which I regularly told the
manager group during performance calibrations – and he was the embodiment of what I like
to call a product-minded engineer. After spending 6 years at Uber, Willem cofounded Rise
Calendar. Disclaimer: I’m an investor in this company, having invested due to knowing Willem
so well after working together for years.

Willem is two and a half years into running his own startup. I thought this a great time to ask
about his experience between working at a startup, and working at a large company, as it’s
the second time Willem has gone from a large company to startup.

With this, it’s over to Willem. The material below is straight from him:

Background

Early in my career, I founded two startups. One was Yunoo, a personal budgeting tool for the
Dutch market. Four years after we launched, the company was acquired by a mid-sized local
company in the enterprise resource planning (ERP) sector. I stayed with this ERP company for
a year. But I had the startup bug in me, and so founded a second startup. This last one was a
great adventure; we went to the US to join the TechStars 2013 accelerator. However, this
startup failed miserably.

I was still recovering from this failure in 2015, when a friend who designed the rst version of
Uber– Jelle Prins – pinged me, and said Uber was kickstarting an engineering o ce in
Amsterdam. By that time, I’d been following Uber for years, and suspected that the
ridesharing industry would only get bigger.

My time at Uber was hypergrowth as its nest. In 2015 when I joined, we had 6 engineers in
the Amsterdam o ce. Six years later, we were at 250 people. For most of my time, I was part
of the Rider Payments team and worked for 4 years with Gergely.

In 2021, I left Uber for Rise Calendar as a technical co-founder. Rise is a beautiful calendar
app that helps you schedule and protects your week. Since then, we’ve raised a pre-seed
round – when Gergely got involved as an angel investor – and have grown the team to 7
people.

Having spent about 15 years split between startups and Big Tech, here’s my honest take on
the good, the bad, and the “ugly” of each environment.

The Software Engineer’s Guidebook: Bonus Chapters Page 1


ffi
fi
fi
ffi
The good, the bad and the “ugly” of each environment

Startups: the good

Learning: Startups are such amazing places to learn in! You usually have a small developer
team, and for the most part, no infrastructure, security, data science, or observability teams –
which are all commonplace in Big Tech. Engineers are expected to jump in where needed,
even when you don’t have expertise.

So you are forced to learn about speci c topics and immediately apply them in production.
Just by doing this, you broaden your expertise incredibly fast in a wide range of topics.

Impact: you can make a large impact and directly in uence the direction of the company, and
very clearly in uence the success of the company, as well. Startups are very at
organizations, meaning you are often involved in strategic decisions.

An example of making a company-wide impact at Rise was during our Christmas hackathon,
when an engineer built a Calendly-like feature for anyone to book a slot in your calendar. It
worked so well that we launched the feature a month later. Going from idea, to adding, to
building and shipping this to all customers, is something you rarely see in bigger companies.

Startups: the bad

Financial risk: Startups tend to pay a lower base salary than Big Tech. They rarely have the
annual performance-based bonuses that are typical at larger companies. Many startups give
equity to engineers, and some startups hand out handsome equity packages to early
employees. Uber is a prime example of this, where early engineers did very well from
generous early packages.

The Software Engineer’s Guidebook: Bonus Chapters Page 2


fl
fi
fl
fl
But let’s be honest, with any startup there is signi cant risk. Plenty of startups fail and close, or
end up being acquired or acqui-hired. Acqui-hiring often means another company takes over
the startup’s team: but does it on terms where investors – or even the founders – don’t see
much of a return on their investment and equity.

Stress: startups are often races against the clock. This focus on speed and execution often
leads to fast context-switching and a working environment with constant time pressure. My
personal experience is that startups are more stressful than Big Tech, where there’s the
option to “lean back” sometimes. This is not so much the case at a smaller company. It’s
important to add that this depends very much on the culture, and my experience won’t be
universal!

Startups: the ugly

Failure: Startups fail, more often than not. This can lead to ugly situations where people lose
their jobs pretty much overnight. Startups are usually a tighter-knit group because people feel
a personal connection to the company and product, much more than is the case in Big Tech.
So shutting down a product or the entire company can be a lot more emotional than a large
company shutting down one of its many products.

Big Tech: The good

Specializing: Big Tech organizations have so many specialized teams! At Uber, they ranged
from mobile feature teams (called program teams – here is some history about this split,)
platform teams, networking teams, and infra ones.

Internal transfers: usually this is surprisingly easy! I’ve moved between teams, and so have
so many engineers, like a Rider Payments engineer who moved over to the Developer
Platform team. Combined with an environment with many specialized teams, and you have a
place where engineers can go really deep in a domain while working on a variety of things.

Financial stability/perks: speaking for software engineers, Big Tech pays well and almost
always issues performance-based cash bonuses. Then there’s the equity granted, which is
more stable and lower risk compared to startup equity.

Joining a Big Tech, and building up a “ nancial bu er” before going to a startup, is something
I’ve seen plenty of engineers do. Things may always go south for a startup, so it’s good to
have reserves!

Networking: One of the most underestimated things about Big Tech is that it’s surprisingly
easy to build a large network while working there! Many of my former Uber colleagues joined
other Big Tech companies, or started a new business – and there’s this one guy who ended
up writing this newsletter which blew up.

I will admit the relationships I built up at Big Tech have proved to be far more valuable in the
long run than I expected!

The Software Engineer’s Guidebook: Bonus Chapters Page 3


fi
fi
ff
Big Tech: the bad

Lack of purpose: In a startup, it’s easy to make an immediate impact for the end-user. I used
to work with Engineer #1 at Uber, Conrad Whelan, who told me this in 2015:

“If an unexpected but important task takes less than 30 minutes, just get it out
immediately! Push it to production.”

Back then, Uber was akin to a startup, and not (yet) a Big Tech business. At Rise, we perform
between 25 and 50 deploys per day with a team of 7. Such a pace generates a ton of energy
in the team. Our end users are amazed when they see a bug they reported xed within
minutes, or when a feature they suggested is shipped a few hours later. This feeling of actual
impact and purpose is much reduced in Big Tech. Also, changes take longer.

Overhead and bureaucracy: on the Rider Payments team at Uber, we had the running joke:
“we’re all just plumbers here 👩🔧 .” This referred to how much “plumbing” was needed to build
even a relatively simple feature. Uber had thousands of microservices, and our team regularly
made changes to more than 20 of them. Many of the changes were simply to proxy a value
from one service to another.

The problem? Each of those changes needed to be approved by the team owning the
service. These teams were in di erent time zones, and so even straightforward “plumbing”
changes could take days to land.

And it got worse. For more complex changes, we usually needed the teams owning the
services to carry them out. So we had a quarterly planning process to ensure all project
dependencies were incorporated into each team’s roadmap. But priorities changed frequently
and – surprise, surprise! – we frequently found ourselves stuck and waiting on other teams.

If this seems to be becoming a rant, it’s because it is. Uber was a fast-moving company, but
also a big company, so things started to take a lot more time. At a startup, when you have a
monolith the same changes take hours, not days.

Big Tech: the ugly

I had to think quite a bit to come up with anything “ugly.” There are plenty of unpleasant
things at larger companies, but nothing terrible. However, one thing really got under my skin.

Misaligned incentives around performance reviews. Doing work that results in a great
performance review is not always the same work that best helps the company. And this can
create pretty twisted, political situations. For example:

A recently joined senior sta engineer decided to propose a project to do a re-architecture of


a system. This person wrote up a neat document that was well thought out, and sent it around
to other senior sta engineers. But there was a problem, this engineer took an existing
document that other engineers had written a few months before, copy-pasted it, changed a
few words, and presented it as their own work.

The Software Engineer’s Guidebook: Bonus Chapters Page 4


ff
ff
ff
fi
Clearly, this engineer was doing this in hopes of demonstrating how quickly they got up to
speed, and how valuable their own, personal contributions were. But by not involving the
original authors, the proposal lacked context that was not in this document – such as why it
wasn’t made, in the end.

This is just one example where pursuing personal recognition, that comes in the form of
performance bonuses, can result in actions that are not in the best interest of the company.
Anyone working at a large company sees things like this.

Which is better?

This is Gergely again.

Thanks Willem, for that dose of honesty! I have to admit I always suspected Willem would go
back to working at – or founding – a startup. It was pretty clear that the more “Big Tech” Uber
became, the more frustrating it was for him to wait on others, versus making code changes
himself. And this attitude made Willem a really productive engineer, as he jumped to working
on something else while waiting on another team. During performance calibration sessions,
as Willem’s manager I had an easy job proving to other managers why he belonged in the top
quartile in most years, thanks to his consistently high output.

Willem’s startup background really helped him get things done, and not wait on others. At the
same time, now that he’s on his third startup, I cannot unsee how his Big Tech experience of
structuring things, planning ahead and building reliable systems, has proved very valuable.

Spending time at a large company and a startup, is probably as good as it gets. Both
environments have very di erent dynamics, and you need to lean on distinct skills to succeed
in each. A more common path I see is devs going from startups to Big Tech because of the
increase in compensation. Although not as frequent, I also see plenty of people go the other
way, from Big Tech to startups. This step feels like a bigger adjustment, especially for those
who have not worked at startups before.

Growing your network is indeed an underrated bene t of working at a larger company, either
Big Tech or a fast-growing scaleup. You can meet so many more people at these companies,
and this is even more true if you move teams, or the company is growing quickly. I echo what
Willem said about how it’s only years later that you appreciate this value. For example, for The
Pragmatic Engineer Newsletter, the rst few interviews were all with people I met and worked
with at Uber: Ganesh Srinivasan, Adam Rogal and Sophia Vincent.

The Software Engineer’s Guidebook: Bonus Chapters Page 5


ff
fi
fi
Bonus #2: The Seniority Rollercoaster
In tech, switching jobs almost always comes with either a nancial or a title upside. However,
it doesn’t always come with both. Switching for higher compensation can result in a “lower”
title, like going from Senior Software Engineer to SWE 2 or VP Engineering to Senior
Engineering Manager.

This is what I call the seniority rollercoaster.

The seniority rollercoaster

Reasons for Down-Leveling

There can be several reasons for receiving a down-level in title while getting an increase in
compensation. The most common are these:

Titles across companies can have di erent expectations – and compensation. For example,
a senior title at Big Tech typically expects more from an engineer than a small developer
agency, a non-tech- rst company, or a recently founded startup does.

Senior positions at Big Tech will also pay more in liquid compensation than many other
companies. Also, some people with a senior title at a smaller company might not – yet – have
the hands-on experience of working at the scale and complexity of these bigger places.

Tiers of companies pay di erently. The tech compensation landscape is becoming


increasingly trimodal, where compensation for the same job title can di er by up to 3 to 5
times across di erent "tiers" of companies. However, a title cut can still mean a signi cant
compensation raise and a new challenge, when going from a lower to a higher-tier company.

The Software Engineer’s Guidebook: Bonus Chapters Page 6


ff
fi
ff
ff
fi
ff
fi
Compensation across tech is rising rapidly. People who stay at the same company for a long
time can get left behind compared to their peers, especially if the company does not move
internal compensation bands to keep up with new o ers. People who worked at the same
company might have lower compensation expectations as a result. Given the choice of a
signi cant raise and a "title" cut, most people will take the title cut when switching jobs.

Changing both companies and technology stacks might result in a lower-level o er from
companies which focus more on expertise with the speci c technology. This is especially true
for agencies, and non "tech- rst" companies which judge candidates by years of experience
in a given technology, over evaluating more holistically.

My two cents is that this type of leveling makes little sense because an experienced engineer
can quickly pick up a new technology, building on their experience. Still, down-leveling, for
this reason, is common with roles where interviews are focused on depth in a speci c
technology.

Interview performance as perceived by the people doing the hiring. How a candidate does
on the interview almost always feeds into leveling decisions and is the most common reason
for down leveling. Candidates whom interviewers are unsure about, would often get o ered a
level below the position they interviewed for.

Down-leveling is especially common in big tech because expectations are typically high,
onboarding takes longer than at smaller places, and companies often aim to hire people who
"raise the bar" at a given level. I've talked in detail about the conservative nature of big tech
hiring.

As a caveat, there are many cases where leveling decisions have already been made even
before the interviews. Based on the candidate's resume and their perceived experience, they
typically interview for a speci c position.

Having competing o ers or being willing to walk away from a down-level might help avoid
down-leveling when your interview performance happens to be perceived right between two
levels. A few people shared how when they showed competing o ers from similar "tier"
companies at a higher level or rejected an o er, they received an o er at the next level.

As a hiring manager, I can understand why: this signal makes hiring managers re-examine
interview feedback and could - in some cases - tilt a "maybe" feedback towards a "yes".
Having a signal that another, similar, company levels the person higher also carries an
additional signal: the threat of the candidate choosing that other company. Leveling decisions
are often down to nuances: and information like this can push those nuances upwards.

The Software Engineer’s Guidebook: Bonus Chapters Page 7


fi
ff
fi
fi
ff
ff
fi
ff
ff
ff
fi
ff
Handling Down-Leveling when Switching Jobs

You got an o er at a level that is “below” your current title but the compensation is more than
you currently make. How do you proceed?

Know that down-levels are common when moving to “up a tier.” There’s an invisible tiering
of companies based on what they expect from engineers at each level. At the top would be
the likes of Google, Facebook, and similar Big Tech companies, where engineers impacting
millions or more of customers with each change can be common. Engineers are expected to
know about – and follow – more processes and best practices, compared to companies
where leadership is not as technical, or the impact of an engineer is magnitudes lower.

It should be no surprise that a senior engineer at an agency building niche apps with
thousands of users has di erent – and easier to meet – expectations than the senior
engineer building an app with hundreds of millions of users.

Rina Artstain, Tech Lead at Dropbox notes how once you move from a “low-tier” company to a
“high-tier” one, down-levels should not be common, going forward:

"This is exactly my experience moving from a low-tier company to a high-tier


company, but moving within high-tier companies will usually not have the
rollercoaster e ect. And when it comes to a speci c tech stack - what's expected
from you as a senior SWE is to have a wide view of the org, know how to make
things happen by getting support from stakeholders, mentoring others etc. They
expect you'll catch up on the stack pretty quickly."

Do your research on what this “lower” title means at the new company. Ask for the
de nition of the level and about the next one as well, so you can evaluate whether you are
missing skills or experience needed for that level. If so, it might be your opportunity to gain
these. All companies with a strong engineering culture will have well-de ned competencies
and clear expectations at di erent levels.

For example, at Skyscanner, the principal level is one level above senior, and Skyscanner has
roughly one principal engineer for every 15 - 30 engineers. Principal responsibilities range
from squad-level, impacting 10-15 engineers, to org-level impacting closer to 100 engineers,
depending on the person and the speci c principal position and senior+ archetype.

Compare this with Uber, where the principal level is four levels above senior and two above
sta . Uber has 1 - 2 principal engineers for their 4,000 software engineers. Principal
responsibilities are company-wide. To attempt to compare the two; a principal engineer at
Uber could have an “impact radius” which is between 20 - 100 times bigger than that of some
principals at Skyscanner, in terms of engineers whom they in uence. Of course, the two
companies are di erent so any comparison is, at best, an apples-to-pears comparison.

Talk with the hiring manager if you disagree with the leveling. Voice your disagreement,
show examples of your past experience, and ask if the hiring committee can consider you for
the next level. You have nothing to lose and everything to gain, as long as you do this in a
respectful way.

The Software Engineer’s Guidebook: Bonus Chapters Page 8


fi
ff
ff
ff
ff
ff
ff
fi
fi
fl
fi
When I was a hiring manager, several candidates have challenged leveling decisions. In every
case, this made me take a closer look at interview signals and expectations for the level. In
some cases, after gathering more information, we o ered the next level, as we'll discuss in
the "Handling down-leveling as a manager" section.

Consider rejecting the o er if you still disagree with leveling. Titles do carry signi cance
both for your career and to signal your status within the organization. If, after getting more
information, you disagree with the assessment, consider rejecting the o er.

Interviews will always have a subjective component and this will always result in false
negatives. These false negatives will result in either not extending o ers to candidates who
would excel at the job, or extending an o er a level lower than they merit.

As a hiring manager, I have been on the receiving end of candidates rejecting o ers because
they disagreed with the leveling. I respected their decisions, and these rejections usually
prompted us to double-check if we did leveling fairly and communicated expectations
correctly. In some cases, candidates who respectfully rejected a position at Level X, we later
contacted, re-assessed, and hired at Level X+1. They were right not to accept a level they
deemed incorrect.

What happens when people knowingly accept down-level o ers? I experienced this rst-hand
as a manager, and it was not pleasant. Down-levels impact managers and if left unchecked,
can also impact teams.

Getting Ahead of Down-Leveling as a Manager

I was starting my rst 1:1 with a recent hire on my team. He jumped right in:

"My rst question is: how do I get to the next level? It's clear that I've been down-
leveled during interviews and that I should be at the next level. My goal is to get
there in six months. What do I need to do?"

I was taken aback. How do I respond? I was used to having rst meetings with people who
were excited to get to work. Yet here I was with someone clearly frustrated on their rst day of
work, all thanks to a leveling decision.

If you thought down leveling is only a problem for those who got down-leveled: it is not. It's
just as much of a problem for their manager, and if handled poorly, it can spread and become
a morale problem impacting the whole team. Here are things you should do to stop this from
happening.

Be on the hiring loop for future team members. Down-leveling often goes unnoticed in
larger organizations where hiring is done by rotating hiring managers and interviewers on
loops. The team for a future new joiner is often only con rmed well after an o er is made, and
is based on org priorities.

My organization at Uber hired like this at times. I made hiring decisions for people who joined
another manager's team, and other Engineering Managers (EMs) extended o ers for people

The Software Engineer’s Guidebook: Bonus Chapters Page 9


fi
fi
ff
ff
ff
fi
fi
ff
ff
ff
ff
ff
ff
fi
fi
fi
who would later join my team. While this setup was easier to manage in terms of time
commitment, it came with downsides. One of these was down-leveling decisions I was not
aware of, until the person joined.

Be the one extending the o er and do a "temperature check". At larger companies,


recruiters can be the ones extending o ers without the hiring manager being present. While
this saves time for the future manager, it also means they miss signs of the candidate being
unhappy with the level.

At Uber, I always tried to be present when we presented the o er. I asked them how they feel,
not just about the numbers, but the position itself. I often picked up the candidate was
unhappy about the title at this point and made sure to follow-up about it.

Dig deeper if you suspect a down-level at play with leveling. If when reviewing the interview
feedback, you get suspicious that the level being o ered is too low, take action. Con rm if the
signals collected in the interview point to the candidate possibly being down-leveled. Signals
that can indicate the wrong level being o ered include the majority of interviewers being very
strong supporters of hiring. A strong hire decision on a loop that was set up for a level below
what the past experience for the candidate might point to, can also be a ag.

When in doubt, get more signals to correctly level. The best way is to hold a follow-up
interview to ll the gaps on signals that might have been missed. It's a good idea to bring in
people calibrated to interview at the next level, share context with them, and ask them to
focus on the gaps. After gathering this additional signal, you should be clear on what the right
level is.

Explain the rationale and what's in it for them if they join. Assuming you've con rmed the
level is the correct one, take the time to explain to the candidate why. I prefer to share what
the expectations are at their current level and the next one. I also aim to be clear about the
areas that they need to grow in, to eventually get that promotion.

This conversation is a great opportunity to commit to helping this person grow professionally,
should they join. Explain what support you and others on the team can lend, the types of
projects they'd work on which expand their expertise, and the challenges they'd face in this
environment.

Set realistic expectations on promotion timelines. Aim not to have people accept an o er
with the false hope of being promoted on an unrealistic timeline. At most larger tech
companies, promotion within a year seldom happens. Even at smaller companies, promotion
within this timeframe is more of an exception.It almost always points to mis-leveling at hire.

Avoid promising promotion timelines when you are not the nal decision maker on
promotions. Such promises only result in frustration when the time you’ve mentioned comes
around, and your direct report has not yet been promoted. It won’t matter that the promotion
is outside of your control; they’ll remember you promising a timeline that did not happen.

If your hands are tied in changing levels, be as up-front as you can be. There will be cases
when you determine the candidate should be o ered a level above, but you cannot do so.

The Software Engineer’s Guidebook: Bonus Chapters Page 10


fi
ff
ff
ff
ff
ff
fi
ff
fl
fi
fi
ff
This might be due to budgeting, or it could be because of someone up the chain blocking this
decision.

I like to be honest with people when we cannot o er a higher position because of {insert
publicly shareable details}. I then encourage them to consider if they would be happy working
at this level, in this environment, in this team, on these challenges, and with me, for at least a
year with no title or compensation change. If this does not match what they are looking for, I'd
suggest they pass on our o er and keep in touch in case new opportunities open up.

Titles Don’t Matter. Titles Do Matter.

“Of course it doesn’t matter to them.”

Do titles in tech matter more than the impact and context of your work? There are two schools
of thought; those who think they do not and those who have experienced rst-hand just how
much they do.

Anyone thinking titles don't matter, know you are in a privileged position. I was in this camp
for a long time and when I talked about titles, most people around me nodded in agreement
on how little titles matter. The people nodding shared how they were also not
underrepresented in tech and were similarly established as me. Titles simply didn't matter for
us, anymore.

If you're established in tech, or you're in a position where your competence is never


questioned, titles indeed do not matter nearly as much. Assuming that everyone else is in this
group is ignorant thinking, though.

The Software Engineer’s Guidebook: Bonus Chapters Page 11


ff
ff
fi
For those in an underrepresented group, titles make a world of di erence in establishing
credibility. I've talked to many women and other minorities in tech, who all told the same
story. They are continuously challenged on whether they are technical. They have to prove
themselves again and again, to people they have not worked extensively with. Many shared
how they spend a staggering amount of energy to be taken as seriously as counterparts who
have the privilege to regard titles as unimportant because their own competence has always
been taken as a given.

A principal engineer from an underrepresented group working at a medium-sized tech


company said: "Once I got promoted to senior, then to principal, things got better each time.
Still, even with a principal engineer title I regularly get challenged on whether I am technical.
Imagine what would happen if I did not have the title, and the signal it carries."

If you're still in the camp of "titles don't matter", I suggest you read the dozens of responses to
my tweet on this topic and the viewpoints of people from underrepresented groups.

Clarify what the title means in the career ladder of the company you’d move to. Across
tech, titles are not standardized, from what "entry-level" means at companies to what "senior"
refers to. It is especially true above the senior levels. Lead, sta , and principal can all have
vastly di erent responsibilities; just take the disconnect in the meaning of principal engineer
at Skyscanner and Uber.

Ask to see the career ladder at the company. Clarify expectations and con rm that the level
would re ect the skills and experience you bring to the table. What would progression look
like? How does it compare to where you are right now?

For example, a principal engineer having an impact radius of 100 engineers at Skyscanner
might map to a sta -level at Uber, but very likely not to Uber’s principal level, which can be
expected to have an impact radius in the numbers of thousands of engineers across the
company.

Takeaways

To avoid down-leveling when changing domains, try to switch tracks within your existing
company when you have the opportunity to do so.

Lateral moves – ones with no title change – can end up helping your career in the long run.
Many times, these can feel like a down-level – especially if you are on track to get promoted
to the next level – and a lateral move does extend this timeline. However, the additional
experience is something that might help you signi cantly in the long run.

On top of titles, understand responsibilities and expectations attached to the title at the
new place. If you maintain your responsibilities, you’re likely setting yourself up for success.
Taking on too much additional responsibility, coupled with a new environment, might set you
up for less success, while a decrease in responsibilities might result in frustration or boredom.
Senior engineering manager Luciano Holanda shares similar advice.

The Software Engineer’s Guidebook: Bonus Chapters Page 12


ff
fl
ff
fi
ff
ff
fi
Down-leveling can be a natural consequence of moving “up the food chain” from a company
with a not-so-great tech culture to one that is closer to, or at the industry-leading level. With
these moves, a title cut is common and can feel like a fair trade-o . This is especially true if
your learning has plateaued at your current company and moving to a new place opens up
more career progression, more learning, and better nancial outcomes.

As a manager, the more involved you are in the hiring process, the more down-leveling
situations you can notice – and act on. For down-leveling that is no mistake, this is an
opportunity to share career levels, expectations, and growth opportunities for your future
team member. And in cases when the decision is incorrect, it’s an opportunity to x it at the
right time, before a new joiner accepts a level too low for their expertise.

The Software Engineer’s Guidebook: Bonus Chapters Page 13


fi
ff
fi
Part II: The Competent Software Developer
The Software Engineer’s Guidebook covers these chapters for this part:

● 7. Getting things done


● 8. Coding
● 9. Software development
● 10. Tools of the productive software engineer

The two bonus chapters:

● Bonus #3: Advice to myself when starting out as a software developer


● Bonus #4: Getting things done as a developer: exercises

The Software Engineer’s Guidebook: Bonus Chapters Page 14


Bonus #3: Advice to Myself When Starting Out as a Software
Developer
As I look back to over a decade ago, there are a few things I wish I'd started doing sooner.
Habits that could have helped made me grow faster and in a more focused way. This is the
advice I'd give my younger self, when I was earlier in my career as a software developer..

1. Take the time to read two books per year on software engineering

Every time I took the time to slowly and thoroughly read a recommended book on software
engineering, I leveled up. By properly reading, I mean taking notes, talking chapters through
with others, doodle diagrams, trying out, going back, and re-reading.

I wish I had read software-related books in my rst few years as a developer. I only started
doing this around year 5 of my engineering career. Books like C# In-Depth, Clean Code, and
Javascript: The Good Parts all helped me elevate my craft at the time. It's not about me
recommending these speci c books - they are dated ones. What I do recommend is looking
for books that go deeper than what you know now. This could be a book on a speci c
technology, or on software engineering practices.

When I read, I don't do it quickly. In fact, I do it rather slowly. I usually go a chapter or two in
one sitting. I take notes or do highlights. When I'm done, I then recap and often discuss with
others. I've also started writing book reviews on this site, mostly to re ect on what I've
learned. I've picked up these habits the past few years. They helped me grow faster as an
engineering manager: and this habit would have served me well as an engineer. Looking for
inspiration for books? Here is a collection of tech books.

Why books over blogs, videos or talk? I'd actually say books on the side of those. Shorter
formats tend to skim the surface compared to a book, for any topic. Books are in-depth, and
well-organized knowledge. It takes me a few hours to write a post like this, but I've been
working close to a year on my book on growing as a software engineer. I think of books as a
form of slower, but more in-depth consumption.

Don't be ambitious: one book every six months is already great. Pick a book, and spend the
time to properly read it. And after you've read a book or two, I also recommend the book How
to Read a Book: The Classic Guide to Intelligent Reading. I'm serious about this
recommendation.

2. Learn the language you use at work in-depth, to the very bottom

I started coding using PHP and some level of JavaScript for part-time work. At university, I was
taught C and C++, both of which I had little love for. For my rst full-time job, I started doing
C#. I knew a lot of languages at the surface level, but none of them really well.

Two years in, I started to be bothered that I had to rely on senior developers when debugging
my C# code. One of the developers who became my goto debugging buddy always seemed

The Software Engineer’s Guidebook: Bonus Chapters Page 15


fi
fi
fi
fl
fi
to know the ins-and-outs of the depths of the language. He recommended the book C# In
Depth for me to study. And study I did. I went all the way to threading, how garbage collection
and generics work, behind the scenes. I pushed myself through countless hours to
understand covariance, contravariance, and other, di cult to digest topics.

Learning the language I used at work in-depth was one of the best decisions I made. At my
rst workplace, this was accidental and had to do with the senior developer inspiring me.
However, this knowledge became an advantage both at work, and when interviewing for
other jobs. Later in my career, I intentionally dived deep into new languages and frameworks.
At Skype, I was hired as a C# developer. However, we needed to switch over to using
JavaScript and WinJS. So I dived deep into JS and mastered WinJS to the point of me
teaching it through a Pluralsight course.

The more languages you know, the more you can evaluate their strengths and
weaknesses. By the time I moved over to iOS, I knew a few languages pretty well. When Swift
came along, I brie y followed and participated in language discussions, proposing readwrite
re ection to be added to the language's roadmap. Knowing the characteristics of the
language made it easier to decide what strategy my team should use to migrate from
Objective-C to Swift. And the more languages you know, the easier it is to pick up new ones -
and go deep easier, when you need to do so.

3. Pair with other developers more often

I feel like pairing is out of style these days. When I started, both Extreme Programming with
continuous pairing, TDD, and mob programming were popular things to do. Some of my
biggest professional leaps came after pairing with people. These leaps were more signi cant
than reading any book.

A memorable pairing was with a developer who gave harsh code reviews to everyone -
including me. One day I had enough, and I decided not to reply on the code review tool, but
to sit next to them, asking them to walk me through their comments. I ended up learning a lot
- while also telling them I didn't think their comments were fair. They took note and suggested
I pair every time I feel this is the case. This is what I did. This developer had a thing for
performant code, and through my pairing, I learned about the ins-and-outs of potential
performance bottlenecks - and I'd like to think I taught them about maintainability concerns, in
return.

Another great pairing memory was doing TDD with another engineer, where we passed the
keyboard between writing the test and writing the production code for it. We did this for two
days, implementing a tricky part of the system. It's hard to describe how eye-opening this
exercise was. We completely changed our approach midway as we made count of all the
edge cases. And we also formed a strong bond with this developer, which would last for
months after.

4. Write unit tests and run them against a CI

The Software Engineer’s Guidebook: Bonus Chapters Page 16


fi
fl
fl
ffi
fi
Senior engineers often talk about the importance of unit testing. But the whole thing seems
so counter-intuitive. Why would you spend more time writing trivial-looking tests? This was my
approach for testing for some time.

In order to appreciate the value of unit testing, you need to have that "aha!" moment, when
unit tests you wrote to save the day. However, to get there, you need to grunt away, and write
those tests, have them run against a CI. And you often need to do it for months, before you
get that "aha!" moment.

For me, I had two of these moments. The rst one was when I built the backend engine, as a
side project, for a tiny online casino. The API was managing real money, and I was terri ed of
making mistakes. So I covered all my code with unit tests. The project was late - partially the
tests to blame, as they took a lot of time. But it felt right to do it like this. I handed the project
over to the customer at the end of the contract. Two years later, they told me how those tests
had saved the team multiple times, who were about to push bugs in production - had it not
been for tests breaking.

My other "aha" moment was building Skype on the Web. We built a green eld, Google
Hangouts competitor on web.skype.com. The team was a strong one, and we had full unit
coverage and heavy integration testing. Three months into the project, an engineer decided
we need to refactor the structure of the whole project. It was a very risky refactor, and all of us
voted not to do it.

The developer challenged us that given the test coverage, it should be a piece of cake. If the
tests pass, it works. I was skeptical. But that's exactly how it worked. After a week-long
refactoring, he pushed a giant change... and nothing broke. Not then, not later. All tests
passed. This was when I realized the safety net that a strong test suite gives and how it allows
refactoring without fear.

5. Make refactoring a habit and master refactoring tools

For many years, I preferred to make the smallest possible change in the codebase, when I
was working with a team. For my own, personal projects I did massive refactorings - but I was
never comfortable doing this on codebases I did not fully own.

Then I met an engineer at Skype who would continuously do small or large refactors. They all
made sense, and the code always got better. And they never messed things up. How did they
do it?

As I paired with them, they knew their IDE very well and had refactor extensions added.
Extracting a method, renaming a variable, moving into a constant... it took them a second of
time.

I realized I was afraid of refactoring as I missed both the practice and the tools to do this
well. As I started making refactoring a weekly habit, I got better at both. This habit served me
well later on - I just wish it didn't take me so many years to start it.

The Software Engineer’s Guidebook: Bonus Chapters Page 17


fi
fi
fi
6. Know that good software engineering is experience. Get lots of it.

When I started out, I used to be intimidated by senior engineers. They saw bugs in my code
that I didn't. They knew answers I had no clue about. I assumed they're just smarter and
better than me, and accepted this is how things are.

Now that I've worked with many great regarded software engineers closely, and coached
several more, I see that there's nothing to be intimidated about. The best software engineers
have a mix of learned knowledge and real-world experience. The knowledge you can learn.
The experience, you need to go after.

Look for opportunities to work on di erent stacks, di erent domains, and challenging
projects. It took me seven or eight years to get what I would consider a "senior" level. I see
some people joining high-growth places like Uber get there in three or four. The di erence?
Those people work on challenging projects, pushing just to keep up with the others around
them, and often change teams midway, to start again. They volunteer to work on new projects
and try out new technologies as the rst in the team. I eventually became this person - but not
for my rst few years.

7. Teach what you learn

The best way to learn something is to teach it. I started doing this accidentally. In 2010, I
started presenting on .NET and Windows Phone user groups. My presentations were not
good, but I learned lots just by preparing for them.

These days, when I want to learn something well, I sign up to do a public talk about it. I
o ered to do a presentation on how Uber rolls out backend changes at scale in 2017, a year
after joining Uber. When I did, I didn't fully understand how we did this - I was mostly doing
mobile development until then, and managing a mobile team. By the talk, I had no choice but
learn all the details. And I had plenty of pressure to do so: about a hundred local developers
signed up for that event.

Many other people swear on this method working - with Shawn "Swyx" Wang being a
prominent gure of the #LearnInPublic approach. His growth story is far more impressive than
mine: going from changing careers to senior engineering roles at Netlify and AWS in four
years, and writing a book about his learnings. The nice thing about teaching others is you can
only win. Not only will you learn something by teaching, but you'll also help and inspire others.

And I don't know any experienced, role model developer who is not a decent teacher and
mentor. The earlier you start giving back and teaching, the more natural this will come.

The Software Engineer’s Guidebook: Bonus Chapters Page 18


ff
fi
fi
fi
ff
ff
ff
Bonus #4: Getting Things Done as a Developer: Exercises
The more you are perceived as someone who “gets things done”, the faster career
progression and more growth opportunities you can expect. You are also more likely to
become a “goto person”, and one who is given stretch opportunities.

Here are exercises you can do to get better at getting things done.

Break down and track your own work. At the start of the week, make a plan of the work you
need to do. Make a list of tasks: from ones like coding a feature, to testing, documentation,
preparing for meetings, and so on. At the end of a week, re ect on which of these you ended
up doing.

Record the unexpected things that take up your time. A surprisingly large part of building
software has nothing to do with coding. You’ll nd much of your time spent talking to people
to discuss how to solve a problem, reading code and documentation, ghting with the build
and tooling, asking - and waiting on - code reviews, doing code reviews, emails and chat, on
meetings and preparing for some of them.

At large companies, you’ll have all-hands meetings and reside chats, mandatory trainings
and a lot more emails and chat rooms. At some places, you might be included in interviews,
onboarding new joiners and company internal or external events.

The sooner you learn what other things outside of software development take up your time,
the better you’ll be able to manage your time, and set expectations. The more senior you
become, the more of your time will be spent on non-coding activities. Becoming good at time
management early on will set you up for success at those senior levels.

Privately estimate how long your own tasks will take: and see how good your own
estimates were. One of the most frequent questions you’ll hear is “how long will {this} take”.
And the less experience you have, the less accurate you’ll be able to answer this. Heck, with
more than a decade of experience I sometimes still don’t have a good idea on how long
building a feature will take, when there are too many unknowns.

There is only one way to get better at estimating: do it more often. And there is no better way
to do it more often, than to estimate everything you do at work: privately tracking your
estimates, and checking in at the end of the week or sprint on how you did compared your
own expectations. If you took much longer than you thought you would, why was it? Did you
run into some unknowns? Did you nd new dependencies? Did you get interrupted too many
times? What was it? Learn from your “missed” estimates: even if no one else knew that you
missed these.

Engineers who keep track of their own work and estimates tend to be better at estimations in
my observation of a few dozen people I worked closely with. Those who have a text le or
private log, with a list and some kind of internal estimation have almost always been better at

The Software Engineer’s Guidebook: Bonus Chapters Page 19


fi
fi
fi
fl
fi
fi
both giving realistic estimations on how long they think their tasks will take and pushing back
on taking on new tasks when they have too much work.

Say “no” when your list is too full to commit. “Hey, can you get this small piece of thing
done by tomorrow?” You’ll get requests like this regularly: from your manager, colleagues or
other stakeholders.

The people who are perceived to “get things done” often are not more productive than
others. However, when they say yes, they do things: this is because they don’t overcommit.
And they also say “no” when their plate is too full.

With a list of things you have to do, and your estimates - even if just to yourself - don’t say yes
to any new request. Instead, say “let me check what else I need to do”. If you have too many
things, tell people you cannot get it done by that short time, or not at all.

And when you do say yes, add it to your list, with the “deadline” you promised.

Tell yourself “I’m blocked!” when you are blocked. You’ll get blocked on many things: from
being stuck on how to make the code work, to not knowing who to talk with about a problem
and many others. The rst step in unlocking yourself is to notice that you are blocked, and
you could move faster with help. Tell yourself “I am blocked”, when you are stuck on the same
problem for more than a given time: say, half an hour.

Ask for help in unblocking yourself. When you’ve noticed you’re blocked: ask for help from a
team mate for next steps. When there’s no one in the team who can help, reach out to your
manager, or other people, outside the team. Be clear with people that you are stuck. Even if
they cannot o er help, ask if they have any ideas for pointers.

Ask for feedback from your manager and teammates. Ask them about how productive and
initiative-seeking they see you. Have one-on-one conversations with your manager and -at
some point - your teammates. Ask them what their view on your productivity is.

You could lead by a question like “Honestly: on a scale of 1 to 5 - where 5 is someone who is
very productive; someone who gets things done - where do you think I am?” Be open to
feedback. If you’re not a 5, ask them what suggestions they’d have for you to improve. What
do you have to learn?

Ask the same on taking initiatives. Ask people “On a scale of 1 to 5, where 5 is someone who
takes as much initiative as expected in my position, where do you see me? Do you have
advice on how I could improve in this area?”

Push code every day. The more senior you’ll be, the more of the non-coding work will take up
your time. This also means that right now, you’ll have more time to spend on coding than
you’ll have later in your career. So be really productive by writing code: by pushing working
code, every day.

The Software Engineer’s Guidebook: Bonus Chapters Page 20


ff
fi
Aim to get at least one new code change or pull request to review every single day: even on
the days when you might have more meetings or other activities. If you can, try to get reviews
on your code the same day, and push the changes. If you work on something that is a multi-
day work: follow this same model. Break down your code into smaller changes, work on a
branch, but push a working piece of code, every day.

You’ll nd yourself approach your work more e ciently when your goal is to make one code
change that works. Over time, you’ll also nd you’ll get blocked less, and progress more
stable. Now is the time to learn how to be productive with coding: every single day. How long
can you keep up your streak?

The Software Engineer’s Guidebook: Bonus Chapters Page 21


fi
fi
ffi
Part III: The Well-Rounded Senior Engineer
The Software Engineer’s Guidebook covers these chapters for this part:

● 11. Getting things done


● 12. Collaboration and teamwork
● 13. Software engineering
● 14. Testing
● 15. Software architecture

The two bonus chapters:

● Bonus #6: Executing a migration: doing it well


● Bonus #7: Getting things done as a senior engineer: exercises

The Software Engineer’s Guidebook: Bonus Chapters Page 22


Bonus #6: Executing a Migration: Doing it Well
Migrations are one of the most overlooked topics in software engineering, especially at high-
growth startups and companies. As a company’s operations grow, new systems and
approaches are adopted to cope with extra load, more use cases, or more constraints. From
time to time, engineers need to migrate over from an old system or approach, to a new one.

And this is where things can get interesting, unexpected… and even ugly.

This chapter is an extensive guide on the process of migration. You can use it as a blueprint
when preparing and executing migrations.

Types of migrations

The word ‘migration’ describes a broad range of activities. Here are the most common types
of migrations we engineers come across.

Service replacement. Replace OldService with NewService and move all customers over to
eventually use NewService. An example is replacing an old, legacy payments system with a
new one like Uber did, in the example above.

The Software Engineer’s Guidebook: Bonus Chapters Page 23


This type of migration is very common at any fast-growing company. There might be many
reasons to write a new service instead of improving the old service, such as:

● The old system not supporting enough business requirements.


● The need to improve nonfunctional characteristics like handling extra load, achieving
lower latency, storing more data.
● The language or framework the old service was written in, is no longer supported or
preferred within the organization.

Service integration. Integrate a new service or approach.

The Software Engineer’s Guidebook: Bonus Chapters Page 24


Examples include:

● Integrate a new API for use. For example, integrate a new payments processing
service.
● Migrate to a new version of an external service. For example, move from the v1 API of
a provider to a v2 API.
● Migrate to a new version of a service where instead of polling for events, the new
service pushes events. Or instead of synchronously consuming inbound events,
inbound events are consumed asynchronously, triggering callbacks.

As the examples above show, service integration migrations can include many things. There
are engineers who might not even consider some of the above to be migrations, but treat
them as a change in functionality. But I argue that we should treat them as migrations.

This is because these are changes where an external service alters, and your code also
changes to ensure correct future behavior. This characteristic is what makes them risky
changes, and why it’s wise to proceed with caution, following a migration playbook.

Service extraction. Move from an in-system dependency to an external one. This is a


common approach at high-growth startups when large services get split up into smaller ones.

The Software Engineer’s Guidebook: Bonus Chapters Page 25


On the surface, service extractions seem like some of the most simple migrations. After all,
we’re just moving code that already works into a new service, right?

Wrong.

Service extractions are much more risky than simply moving code around. There are risks
around networking and the correctness of the new service; especially as the code is rarely
copied and pasted. Also, extracting a service comes loaded with future operational risks.

While service extractions are one of the easiest types of migrations to pull o successfully
without any monitoring or alerting in place, I suggest to avoid this temptation and to follow a
more thorough migration runbook, like that we discuss below.

Code migrations. Moving a part of the codebase to use a di erent framework, library or a
programming language.

The Software Engineer’s Guidebook: Bonus Chapters Page 26


ff
ff
The biggest challenges of this type of migration are:

● Large-scale change. It’s not uncommon to have to change a very high number of les
and lines of code.
● Hard to rollback. Because the change is so large, it’s also di cult, or sometimes
impossible, to easily roll back the change. This is the opposite of most code changes
which are small and can be unwound very easily.
● Harder to test in production. As the change is large-scale, it can be harder to test the
full change under production tra c.

A few examples of code migrations:

● Migrating to a new language. For example, Stripe migrated 3.5M lines of code over a
weekend, from JavaScript type checked by Flow to Typescript.
● Upgrading to a new major version of a library, which introduces API-breaking changes.
● Changing coding patterns across the codebase. For example, updating a JavaScript
codebase to use promises instead of callbacks.

Data migrations. Migrating one or more databases to a new schema or database engine.

The Software Engineer’s Guidebook: Bonus Chapters Page 27


ffi
ffi
fi
Data migrations are one of the most risky types of migrations. There are several reasons why::

● Di cult to roll back. When code is changed, it’s easy enough to roll back a migration
by rolling back the code. But this isn’t always the case with data.
● Di cult to do in an atomic way. Ideally, a data migration is done as an atomic step.
From one moment to the next, the old database or schema stops being used and all
data moves to the new database or schema. But in practice, moving data takes time.
This is why it’s much easier to do a data migration with downtime.
● Data migration is often tied to code changes. For the migration to work as expected,
code changes often need to be made at the very same time as the data is migrated.
● More edge cases to worry about. You will need to worry about edge cases like
producers writing to the old database or using the old schema, or consumers not
being able to understand the new schema.

Infrastructure migrations. Move storage, computing or networking infrastructure to a new


provider or a new location.

The Software Engineer’s Guidebook: Bonus Chapters Page 28


ffi
ffi
Infrastructure migrations are the most risky, as they impact all services using that
infrastructure. An infrastructure migration gone wrong can take down all dependent services
with it. For this reason, these are the ones that typically need more preparation than even
data migrations.

While all other migrations are virtual in the sense that they typically involve moving code or
data, infrastructure migrations are when the physical infrastructure might also need to be
moved or changed, and onsite work might be needed. Although most companies use cloud
computing providers like AWS, Azure or Google Cloud, plenty of companies still operate their
own data centers, or run their own server boxes. Infrastructure migrations can mean changes
to these as well.

Service and tool upgrades are also changes which can cause outages. Examples of this
include upgrading the CI/CD system to the latest version, updating JIRA to a new version, and
other tooling infrastructure changes.

But for upgrades, the vendor of the tool is the one performing the migration. It’s advisable to
understand how this migration happens under the hood and if it’s a high-risk upgrade, and to
use the approaches in this article to reduce the risks of the update.

The focus of this article is service migrations, and we’ll have a section on data migrations as
well. Infrastructure migrations are out of scope, both because of the complexity, and also
because they’re also the least common type of migration.

The Software Engineer’s Guidebook: Bonus Chapters Page 29


Preparing for migrations

Migrations are risky and when they go wrong, they can cause all kinds of signi cant damage.
However, if you do some groundwork before starting the migration, you’ll reduce risk, gain
con dence and understand the scope of the migration better. Here are a few things you
should do:

● Understand the reason for the migration. Why is this migration needed? What is
wrong with the old solution? What is the impact of the old solution being unsuitable?
What would happen if this migration did not complete?
● What were the constraints in the past? When a migration is needed, it's because the
current solution fails to meet a particular requirement. This could be availability,
performance, or something else. Outline what these capability constraints are. You’ll
need to make sure the new system solves for these past constraints.
● A map of the di erences of Old vs the New. Outline the old system vs the new
system. What is changing and why, and how do these systems work? Are external
interfaces changing at all? Are you adding or removing functionality for the new
system?
● Consumers and producers needing migration. Which customers of the old system
need to be migrated to the new one? Map customers of the old system. Will all
consumers move over, or will some remain on the old system?
● Write and share a migration plan. Write up how the migration will happen. What are
the migration steps? Who will do each step? For example, who will build the new
service, who will migrate each of the consumers, and who will monitor the progress of
the migration? Put this plan in writing and share it with consumers whom the migration
will impact.
● Capacity planning. What load is the current system under? What load will the new
service need to handle? For load planning, don’t only look to the time of the migration,
but look ahead into the future. How will you ensure the new system has the capacity
to handle this load? How will you con rm it can handle the load?
● Error budgets. For complex and large migrations you can expect some things to go
wrong. You might also have migrations where you expect a small percentage of tra c
to not work as expected. Instead of just accepting things going wrong, budget for it.
What is the acceptable limit for errors during the migration? This could be de ned as
latency degradation, % of data that is not consistent for a certain time, percentage of
application errors during the migration, and so on. By de ning error budgets you’ll
also have to measure them to keep yourself honest.
● Edge cases. What are potential tricky situations you need to take into account? Write
these up, then share it with the team working on the migration and all consumers
impacted, so they can also add their edge cases. Common edge cases you should
worry about include:
○ What happens with data producers during migration? For example, say you
have processes writing to the database. What happens when the migration
happens? Will these writes continue? Will you stop them? Will they be queued?

The Software Engineer’s Guidebook: Bonus Chapters Page 30


fi
ff
fi
fi
fi
fi
ffi
○ How will service consumers behave during migration? Will there be edge
cases when clients behave in unexpected ways, or experience data
consistency issues as they interact with a system undergoing migration?
● Security audit of migrations. What are the attack vectors during and after the
migration? Are there vulnerabilities a bad actor could take advantage of, as the
migration happens? Vulnerabilities might not be strictly related to the code or data,
they could include phishing attacks.

This is exactly what happened to NFT marketplace OpenSea, in February of this year.
The company announced a week-long migration to customers. A bad actor realized
this migration was an opportunity for an attack and sent out emails that looked like
they were from OpenSea, asking customers to take action for the migration to
happen. Customers then were tricked into authorizing a smart contract they believed
was from OpenSea, and dozens of unlucky customers lost over $1.7M in NFT assets.

Had the company predicted such phishing and sought to counter it, they could have
chosen to either shorten the migration window, communicated the phishing risks, or
have monitored suspicious smart contracts authorized during the migration period,
and warned users against executing them.
● Run a migration pre-mortem. As engineering director Nathan Gould suggests:
● “One of my favorite migration practices is to hold a ‘pre-mortem’.
The basic play is:
- Write up a migration plan
- Gather the team running the migration, plus stakeholders
- Brainstorm stu that could go wrong
- Identify and prioritize ways to mitigate risk”

Preparing for data migrations

Data migrations bring additional complexities of their own and tend to require more thorough
planning. Some additional complexities you might need to consider are:

● Too much data to migrate in one go. In the case of service replacements, this means
that the new service might need to still use the old service to look up older data. In
this scenario, smart approaches could be used. For example, when modifying a
record, the new service might create a copy from the old system, and stop using the
old system for that record.
● How will data producers be migrated? What happens with data-producing processes,
for example, processes writing to the database at the time of the migration? Will they
be paused? The writes queued? The writes dropped?
● Active-active challenges. When using an active-active data storage setup –
distributing data across several clusters for resilience – you’ll have additional
challenges when migrating. If migrating with downtime, you might be able to migrate
all clusters during this downtime. However, if running a zero-downtime migration,
consumers will see inconsistent data. How will they deal with this inconsistency?

The Software Engineer’s Guidebook: Bonus Chapters Page 31


ff
● Rollback. If the migration has issues, how will you revert to the previous state? When
utilizing downtime to perform the migration, the rollback might be as simple as not
switching over to the newly migrated data. However, with zero downtime migration,
you might need tooling to write back data committed to the migrated database as you
roll back to the old database.
● Disaster recovery considerations. In the event of a major issue like data corruption or
a ransomware attack, how easy is it to roll back to a pre-migration state of the system?
Are there su cient backups? Should you make a last snapshot save before the
migration proceeds?

Pre-migration steps

You have a plan in place and are con dent you have the edge cases covered. Can you start
the migration? Almost certainly not yet! First, you’ll need to ensure you have monitoring in
place so you can track the status of the migration and detect problems. You’ll also want to
validate that the migration will work with shadowing, dry runs and other processes.

Monitoring
Monitoring the migration is the single most important action which can make a migration
successful, and detect one going wrong. The lack of dedicated migration monitoring is the
reason for most migrations causing outages, in my experience.

● De ne what needs to be monitored. How can you tell if the migration goes well?
What do you need to measure to know that customers are not being impacted and the
service is healthy? For data migrations, how can you measure that the data is not
corrupted?
● Build the monitoring systems. Put in place the graphs, tools and alerts that tell you if
the migration is healthy or if it has issues.
● Throwaway monitoring is to be expected! Many engineering teams are hesitant to
build monitoring as they’re used to building graphs and alerts for permanent features.
Break away from this thinking! You need to build monitoring and yes, it will be
removed once the migration is done.
● Do you have monitoring for all error budgets? Remember how you de ned your
error budgets? Make sure there’s monitoring for all of those metrics.
● If it’s painful to build one-o monitoring, take note for later. At companies which
have invested heavily in platform teams, building monitoring for migrations should be
a breeze. If it’s not, then you should incentivize making it easier to do. Do this by
contributing to tooling, or by pushing management to invest in tools, be it via internal
platform teams or contracting with vendors.

Validation
Validate that the migration will work as expected. Once you’ve completed most of the
development work for the migration, you’ll want to hold o rolling out in production. Instead,
you should validate the migration with production data and tra c. Here are some common
ways to do this.

The Software Engineer’s Guidebook: Bonus Chapters Page 32


fi
ffi
ff
fi
ff
ffi
fi
Shadowing, also commonly referred to as ‘parallel run’ or ‘shadow loading.’ This is a common
approach, both with service replacements and service integrations. This approach means
sending all production tra c to the new system or new integration as well, and monitoring
that it works as expected.

Shadowing production tra c.

Shadowing has several bene ts:

● Migration issues are caught early.


● It’s as close to pre-production testing as it gets.
● It serves as load testing. If your shadowed system can handle production load, you
can be con dent that it won’t have issues when switching over.

There are a few caveats with shadowing:

● Shadowing validation. You’ll likely need to build shadowing validation tooling to


con rm the new system works as expected.
● Mocking might be needed to avoid side e ects. The new system might need to mock
certain functionality. For example, if you are migrating an old system which also sends
emails in certain scenarios, you’ll want to stop the new system from sending emails
while in shadowing mode. Doing so would result in emails sent twice!

The Software Engineer’s Guidebook: Bonus Chapters Page 33


fi
fi
ffi
ffi
fi
ff
● Not always practical. There may be times when shadowing is not an approach that’s
pragmatic. This is the case when you would have to mock much of the shadowed
system’s capability. For example, if you are migrating the email layer in an application,
shadowing email sending without sending emails might be meaningless.

Load testing is a common approach to con rm that the new system has the capacity to
handle future, increased loads. While shadowing can give a sense of current load-handling
capability, the goal of load testing is to simulate extreme loads.

Common ways to do load testing are these:

● Use mocked or generated data. Generate test data and execute a load test. The
bene t of this approach is that you can tweak the load test characteristics easily. The
downside is that the test data will not exercise edge cases which only real-world data
has.
● Use production data, but in bulk. A more common load testing approach is to
sidestep test data and use real data. Collect production data for a while, then use this
production data for load testing.
● Combine shadowing with a bulk release of production data. We used this approach
at Uber with a system called Hailstorm. It bu ered all production requests coming in
for a de ned time and replayed it in a shorter time window. For example, we released
10 hours worth of production data in one hour.

Performance sampling is an approach worth doing for high-load systems, especially when
you are changing technologies like frameworks or programming languages. It’s easiest to do
when combining with shadowing. What are the performance characteristics of the new
system, compared to the old? How has latency changed, and has resource usage like CPU
utilization and memory usage, decreased or increased?

Do a dry-run of the full migration. Why wait to do the migration in production, when things
may go wrong that cause outages? If possible, do a dry-run migration and inspect whether
things work as expected.

You can combine a dry-run migration with shadowing. Dry-runs are common to do with data
migrations, where this might be the best way to con rm that data moves as expected.

Test for events that will only happen in future. As an edge case, your migrated system might
have to deal with edge cases that only happen on certain future dates. For example, if
migrating a billing system that sends out bills at the end of the month, you’ll want to test that
this functionality works.

The Software Engineer’s Guidebook: Bonus Chapters Page 34


fi
fi
fi
ff
fi
One option is to do shadowing for long enough so that these future events occur, and you
can validate them in real time. However, you might not have the luxury of waiting, especially if
these events happen once every few months, or once a year. In this case, you’ll have to
simulate these events and validate that the migrated system handles them as expected. A
good example is testing billing systems like this:

The Migration

We’ve planned the migration, done pre-migration validation and perhaps even shadowed the
new system, assuming it’s practical to do. Time to start the migration!

Migration downtime
The most important decision in any migration should be whether or not to have downtime for
consumers of the system being migrated. This decision will determine strategies you can use
for the migration itself.

Zero-downtime migrations are when customers notice nothing of the migration. These are
the ones that need the most preparation to achieve.

Doing zero downtime migrations is often a steep learning curve and involves more upfront
work, when done the rst time. However, at companies where zero downtime is the norm, the
amount of additional work drops over time as people get better at it, and at building or
utilizing tools which aid the process.

There will be many cases when zero downtime is too expensive to do, in terms of time spent
building tooling. There will also be cases where it’s not possible, for example, with
infrastructure migrations. However, if you start by considering what it takes to do zero
downtime migrations, then you can make a more informed choice.

I would encourage teams to do at least one zero downtime migration, if they’ve never done
one before. Teams that have never performed such a migration often overestimate their
complexity, and underestimate the bene t of not having to work outside business hours when
doing zero downtime migrations.

Migration with downtime a ecting few to no customers is when you take the system down,
but customers don’t notice anything happened. How is this possible?

For one, your business might be intentionally o ine during certain hours. For example, if you
have systems servicing the stock market which only operate during business hours,
customers won’t notice migrations done outside these hours.

If your migration involves non time-sensitive functionality, you can also get away without
customers noticing. In these cases you might be able to take the old system o ine, queue
incoming requests, do the migration, then replay those requests for the new system to

The Software Engineer’s Guidebook: Bonus Chapters Page 35


fi
ff
fi
ffl
ffl
process. For example, if you are migrating a system that sends out marketing emails,
customers won’t notice – or care – that some marketing emails arrive an hour after they
usually do, thanks to the migration.

Migration with reduced functionality is an approach where you don’t introduce downtime to
a system, but some functionality will go o ine. A common case is to turn a system to ‘read
only’ mode during a data migration; all read operations still function, but new data can not be
written. That data will either be queued for later writing, or it might be discarded until the
migration is complete.

Migration with planned downtime is an approach where you take the current system fully
o ine, perform the migration, then bring the migrated system online. You are able to
accurately estimate the downtime needed and can communicate this downtime, ahead of
time. You typically choose outside peak hours to perform the migration, usually in the middle
of the night for most customers, or at the weekend.

Migration with downtime has the bene t that you don’t need to worry about edge cases of
consumers accessing a system that is not fully migrated.

The downside of this approach – of taking the system o ine – is that it adds pressure; if
something goes wrong with the migration, there’s not much time to x it without exceeding
the communicated downtime window.

Migrations utilizing regular downtime periods is an approach common at more traditional


businesses which have been doing migrations for years, or decades. Several banks fall into
this category, which commonly allow for downtime to happen over the weekend or during
bank holidays.

Having regular downtime periods that can be used for migrations is convenient for
engineering teams. They can use these often long timeframes and not have to worry about a
migration going wrong as they have ample time to revert it, and to get it right in the next
period.

I personally nd regular downtime periods tempt engineering teams to take the easy route of
not preparing well for migrations, and disincentivize zero-downtime approaches. On top of
this, regular downtime periods incentivize working outside business hours like at weekends
or late at night.

The Software Engineer’s Guidebook: Bonus Chapters Page 36


ffl
fi
fi
ffl
ffl
fi
Migration strategies
How will you perform the migration? Here are the most common migration strategies:

Switch over. With a ip of a switch, or more often a con guration chance, you route all tra c
to the new system. This is usually done after extensive shadowing.

There are migrations where a switch over is the only sensible strategy. Code migrations are
one of them, and data migrations might be, too. Migrations that utilize downtime are almost
always ones that use a switch over method once the migration is complete.

Staged rollout. This means rolling out the migration gradually to parts of the system, or to a
certain group of consumers. As the rollout proceeds, the team monitors the system to make
sure it works as expected, and pauses or reverses the rollout when they see issues.

Staged rollouts are popular when releasing new features, gradually rolling them out to all
users. This means that many teams already have access to the tools – like feature ags – to
use for staged rollouts.

Several types of migrations can easily be done as staged rollouts. However, more complex
ones like data migrations or infrastructure migrations often require extra complexity to be
added, in order to use a staged rollout approach. This is because in those migrations, both
data migration and code changes often need to be tied together. A staged rollout with a data
migration might mean writing more code to keep the migrated data and the code executed in
sync; this new code is yet another source of bugs.

Writeback to the old system is a common approach with both service replacement
migrations and some data migrations. In cases where the existing service has many internal
consumers, the migration to the new system does not move these consumers over to the new
system.

Instead, the new system writes data back to the old system, allowing for consumers to
operate without changes. Now, the migration is complete in the sense that the new system
operates as primary. However, there will be a long-tail migration e ort to move all consumers
of the old system to use the new system.

The Software Engineer’s Guidebook: Bonus Chapters Page 37


fl
fi
ff
fl
ffi
Writing back to the old service, allowing non-migrated services to keep operating without
interruption.

Migration toolset
Let’s get to the migration! Here are approaches to consider using.

Go through your migration plan with the team, once more. This should be a document
outlining:

● Each migration step.


● How each step will be validated to con rm it’s successful, so the next step can begin.
● Who does what during the migration.
● Contacts on teams who could be impacted.
● Edge cases that might occur and how those will be handled.
● A rollback plan on how to revert the migration if any of the steps go wrong.

Validate that your migration monitoring is in-place and working. The location of graphs,
alerts and tools are already part of your migration plan: double check they are up. Test that
they work.

The Software Engineer’s Guidebook: Bonus Chapters Page 38


fi
Announce the timing of the migration ahead of time. How much time is enough time for this
depends on the scale and impact of the migration. This could be days’ worth of heads up, or
weeks’. For small migrations, announcing a few minutes beforehand to relevant teams and
oncalls that the migration is starting, might also be su cient.

I strongly suggest not to start a migration without announcing it to teams and stakeholders
which could be impacted. Don’t forget to not only notify engineering teams, but non-
engineering groups like customer support, operations and other people who can help in
letting you know if they see unexpected issues during the migration.

Start! Once the announcement is out, start executing the migration.

If there’s an issue: don’t panic. There’s always a chance that something goes wrong during
the migration. If this happens, keep your cool and respond the same way as you would during
any outage.

Focus on mitigating the issue, instead of xing the root cause. Use the rollback plan in your
mitigation plan. Once you’ve rolled back, regroup to identify the issue and prepare for a new
migration.

If you don’t have a rollback plan, or the rollback is not working, consider asking for a second
opinion before proceeding with anything bold. You’re in the heat of the moment, under
pressure and it’s much easier to miss things in this state. There are few situations where a
second pair of eyes isn’t helpful.

Writing back to the old service, so that non-migrated services remain operational.

The Software Engineer’s Guidebook: Bonus Chapters Page 39


fi
ffi
After the migration

You’ve completed the migration. Congratulations! What now?

Announce the migration is complete. Notify not just the impacted stakeholders, but a
broader group of potentially interested teams that the migration is complete.

If the migration was a non-trivial project, follow the same steps as when wrapping up projects,
that I suggest in the article Software Engineers Leading Projects, including the nal project
update:

“Write a concise summary of why people should care, what the impact – or
expected impact – of the project is, summarize the work, highlight key
contributors, and link to details.

“Shine a light on all team members, and anyone who meaningfully helped with
the work. A nal project update email is the time to praise people by name who
worked on the project. Make sure to not omit key people, which is why getting
feedback on this draft is a good idea.”

When announcing the completed migration, specify where you’d like people to report any
issues they might see as a result of the migration.

Validate that the migration is successful. Con rm that everything works as expected. Don’t
only look at logs and graphs, but look at business metrics and get details from customer
support. Is anything o ? If so, take a closer look.

Prioritize for follow-up work, ahead of new projects. If all goes well, there will be no further
work on the migration. But what if problems surface, such as glitches for certain consumers or
corrupted data?

I suggest you treat wrapping up the migration – and xing any issues coming up – ahead of
starting new work. If the issues are minor, you might be able to resolve them with the help of
the support engineer or oncall engineer, if your team has such a rotation. If they are more
complex issues, you might have to push back plans for future projects in favor of nishing the
migration.

The migration long-tail

In organizations with lots of services, it’s often impractical to migrate all consumers to a new
system. Instead, a writeback strategy is used and the migration is broken up into these steps:

1. Migrate so the new system is primary. This new system uses writebacks or a similar
approach to keep the old system up-to-date and usable by existing clients.
2. The migration long-tail. Migrate existing consumers, one by one, to the new system.
Do this either via the teams migrating as self-service, the migrating team providing
hand-holding, or as a mix.

The Software Engineer’s Guidebook: Bonus Chapters Page 40


fi
ff
fi
fi
fi
fi
3. Shut down the old system. Once all consumers are moved over, retire the old system.
This step is often much later than most teams predict.

I’ve consistently observed the long-tail of migrations to take more time and more toll on teams
owning the migration, than they expected. This often hits team morale as migrations are
thankless enough to do, but they’re especially taxing when they drag on, and the team gets
questioned on why it’s taking so long.

The risk of outages during this long-tail migration is high. It’s common to proceed with great
caution during the rst phase of migrating to the primary system. However, during the long
tail, teams usually proceed with fewer guard rails, and outages frequently occur as consumers
migrate.

Also, the longer the old system is kept alive, the more problems occur because of the
di erence in functionality in the old versus the new system. This is especially problematic if
code changes make it into the new system to support teams, which have yet to migrate to the
new system.

How do you manage this migration long-tail, to make it as e cient as possible? Here are
things to do:

1. Put monitoring in-place for the writebacks to the old system. If the primary system has
issues writing back to the old system, this can lead to major outages, as it did in the case of
Uber. Even though the writeback is temporary, it’s critical you monitor its health.

2. Make it easy for teams to migrate using self-service tooling. Create runbooks, tools to do
dry-run migrations and other ways for engineers owning systems to migrate, test and execute
the migrations themselves. Adopt the platform team mindset by enabling the consumers to
execute the migration. And if your team owns a major migration, chances are you’re either a
platform team, or playing at being a platform team role during this migration.

3. Create visibility on the long-tail migration. Have visibility on:

● Who uses the old service? Which consumers are dependent on it?
● Which features do they use in the old service? This information will help with
prioritizing migration, especially if the new service is missing functionality from the old
service.
● How much do they use it? How often, or with what load?
● How critical is the old service for each team? If the old system breaks, which issues
would it cause?
● When does each consumer plan to migrate? Is this migration in their roadmap? Is this
a soft commitment or a hard one?

4. Get leadership support for the long-tail of the migration. I remember how challenging it
was within Uber to motivate teams to move their systems over to the new payments system,
instead of relying on the old systems that worked ne, thanks to writebacks. Most teams
prioritized shipping business functionality over doing a migration that made no di erence to
their business.

The Software Engineer’s Guidebook: Bonus Chapters Page 41


ff
fi
fi
ffi
ff
It’s true that migrations rarely count in business impact terms for customers which are forced
to do them. And it’s fair that they won’t prioritize them when they don’t think the work is
important enough. This is where leadership comes in.

If a migration is truly strategic to a company, make leadership – up to and including the CTO
or the engineering lead of the organization – understand why it’s strategic. And get them to
prioritize the migration as one of the top initiatives for the organization during annual or bi-
annual planning.

This was exactly how much of the migration e ort to move to Uber’s new payments system
was prioritized, this move became one of the top strategic priorities for the migration.
Suddenly teams had a valid reason to prioritize this work, ahead of some business initiatives.

Without leadership support, large migrations will drag out, and some will never get done. So
get this support as early as you can.

More on migrations
For more details on the people side of migrations (e.g. selling migrations to the business) and
to access a migration checklist, see this The Pragmatic Engineer article.

The Software Engineer’s Guidebook: Bonus Chapters Page 42


ff
Bonus #7: Getting Things Done as a Senior Engineer: Exercises
At the senior level, you get a lot more inbound requests than before. Even as you are working
hard, don’t forget to make sure that others know that you are doing important and good work,
and that you’re getting this done.

Here are exercises to improve both your ability to get more complex things done, and to
ensure that others around you see that you are doing so:

Form a strategy on how to deal with the inbound requests that come to you. There are
many di erent ways you can do this: nd the approach that works for you, by experimenting.
Some possible approaches:

● Block out times for uninterrupted, deep work


● Say “not right now” when in the “zone.”
● Timebox how much time you spend helping out on something
● Turn sync requests to async ones
● Redirect requests when someone else can bene t more from helping
● Know your “#1 priority work” at all times
● Prioritize requests
● Figure out a system how to capture important, but not urgent work
● For anything not important: say no

When your work is done: ensure that it is “properly” done. Moving fast is easy enough:
buying moving fast with quality output is a challenge even for many senior engineers. There
are several things you can do to help increase the quality of your output:

● Write a speci cation on how your work is expected to work


● Have a test plan – ideally even before you start coding
● Collaborate with QA folks (if you are lucky enough to work with them)

Work in short iterations: and be conscious why you deviate from this, if you do. Short
iterations helps you make smaller but stable progress; get frequent feedback; and usually this
approach is how you get things done faster.

There are few, but valid cases when doing longer stretches of work make sense – like when
prototyping, resesarching, or not needing input from others. When you decide to skip short
iterations: make sure you have a valid reason for doing so.

Become product-minded. Understand your customers, and nd ways to stay close to them.
You’ll be able to craft more practical solutions to their problems this way.

Document things. Documenting will help yourself, at the very least. However, there’s a good
chance you will help the rest of your team as well!

Unblock yourself, and others on your team. By now, it’s a baseline expectation that you
notice when you are stuck, and know how you can get unstuck. Getting yourself unstuck
could mean:

● Trying a di erent approach.

The Software Engineer’s Guidebook: Bonus Chapters Page 43


ff
ff
fi
fi
fi
fi
● Asking for a second opinion from peers, or talking through your approach with them.
● Asking for help from more experienced people.
● Setting the problem aside, or working around it instead.

Notice when someone else on your team is stuck, and help them get unstuck. And lead by
example in resolving more challenging blockers for the team, where others might not yet
have the experience that you do, in removing those blockers.

Expand your expertise. You will get much better at “thinking outside the box” if you get
exposure to other domains, technologies and areas. Some ways you can do this:

● Observe and talk to engineers who frequently seem to “think outside of the box.” How
do they do it?
● Broaden your experience: learn new technologies, languages, frameworks.
● Go deep and become an expert in a new area.
● Come up with more than one alternative solution to problems you face.

Don’t assume people know about the work you do: communicate about it instead. Keep a
“work log” that you can share with your manager, mentor, and – perhaps, in some cases –
your peers as well. Share both wins and challenges with your team and manager, and explain
what made longer stretches of work more complex.

Verbalize the business impact of your work, where you can. Knowing – and being clear about
– why your work is important will also help you say “no” to work that might seem important,
but it is less impactful than what you are currently occupied with.

The Software Engineer’s Guidebook: Bonus Chapters Page 44


Part IV: The Pragmatic Tech Lead
The Software Engineer’s Guidebook covers these chapters for this part:

● 16. Project management


● 17. Shipping to production
● 18. Stakeholder management
● 19. Team structure
● 20. Team dynamics

The two bonus chapters:

● Bonus #7: Consolidating technologies


● Bonus #8: Becoming a better writer as a software engineer

The Software Engineer’s Guidebook: Bonus Chapters Page 45


Bonus #7: Consolidating Technologies
An engineering manager asks:

At my company, several languages are used on the backend, and the new CTO
wants to consolidate them. Engineers are grumbling about this, with some
threatening to leave if their language gets cut. What are things to consider with
such a consolidation?

The topic of how to deal with the problem of consolidating technologies is vast. This is
because every situation will be slightly di erent, depending on the context of your
environment, the people, and the history, which led to the problem of too many di erent
technologies being in use.

How do you consolidate several technologies into a smaller subset? A question every
company is faced with, sooner or later.

In this chapter, I o er observations on the most common approaches I’ve observed, with
advice on how to go about consolidating technologies once you’ve decided to go ahead with
it. In this article, we cover:

Extreme #1: the “anything goes” approach

Let’s assume we’re at a new company, building a new product. We’re a startup which expects
to grow fast, and wants to avoid the characteristics of many enterprises: slow moving,
autonomy not given to engineers, technology choices dictated from above. So, let’s do the
opposite.

The Software Engineer’s Guidebook: Bonus Chapters Page 46


ff
ff
ff
Teams and software engineers are free to choose which technologies they want to use, as
long as they move fast and get things done. We might even record this principle as a part of
the engineering culture summary which is put on the o ce walls – or virtual collaboration
spaces, if we’re a full-remote company.

Initially, things go great! The team is happy, productivity is good, and we see some other
bene ts.

Initial upsides of this approach, which you’ll likely observe:

● Autonomy. We give engineers the choice of which technology to use. There’s no


grumbling about being forced to use some legacy technology, as engineers are
making the choices.
● Hiring. It’s easy to hire engineers, as we don’t xate on experience with a given stack
– at least not at rst. Engineers with experience across a variety of technologies join
the company as early hires.
● Lots of fun and experimentation. Thanks to the policy that any technology goes,
some teams try out brand new tools, perhaps becoming some of their earliest
adopters. This freedom means exploration and fun for many engineers!

But downsides appear, over time. Once the honeymoon period ends and the company
grows, cracks begin to appear in the ‘anything goes’ approach:

● Working across services and teams is challenging. Since each team has chosen a
di erent set of languages and technologies to use, it’s hard for engineers to work
across teams. On the backend, this is usually especially the case. For example, at
Uber – where initially, anything went – my team often needed to contribute to
microservices written in Python, Node.JS, Java and Go. Doing so meant engineers had
to get up to speed with all these languages.
● Hiring becomes more challenging. Software engineers with experience of a speci c
technology might be hesitant to join a team using a very di erent set of tools.
Similarly, closing specialists with deep expertise in a particular technology is also more
challenging.
● Onboarding gets more time consuming. New hires need to become familiar with
systems written in di erent languages and frameworks. Before becoming productive,
they need to rst familiarize themselves with those languages and technologies.
● Internal mobility can be more limited. Moving teams is easy when the tech stack is
familiar enough for an engineer working on Team A to easily contribute to work on
Team B. But with a varied tech stack, an engineer moving to Team B must rst become
familiar with the stack Team B uses.
● Maintaining systems. If working across teams is challenging, then hiring and
onboarding are more di cult, and dealing with people coming and going gets tricky.
● Challenging to put in place platform teams / developer experience (DevEx) teams.
As the organization grows, platform teams and DevEx teams are a natural way to
create more leverage for software engineers building products. However, with a long
list of technologies, it can be challenging to decide what platform teams or DevEx
teams should focus on.

The Software Engineer’s Guidebook: Bonus Chapters Page 47


ff
fi
fi
fi
ff
ffi
fi
ffi
ff
fi
fi
● The need to consolidate comes up more frequently. The initial bene ts of full
autonomy are outweighed by a growing list of pain points. Software engineers and
engineering leaders will likely both start to recommend some sort of company-wide
consolidation.

CTO Zoë Nolan – whom I worked with at Skype – shares a story about how the ‘anything
goes’ approach ended up being a mistake:

“At a previous start-up. Green eld project. New team. We got started with building version
one. We began as a free for all. The mindset was the best tool for the job. Resulting in every
service being in a di erent language. Node, Go, Haskell, Python.

For the minimum viable product (MVP), everything was in containers, so deploying and
running the system was not that bad. (...) Maintenance or anything post-demo got zero
thought. We needed to ship sometime that vaguely worked.

Post MVP. Maintenance was a problem; only certain people could work on certain services.
Hiring was the other major problem and ultimately forced the issue. No one knew all those
languages. Even people that knew two or three of them were not at the same level in all the
languages. Mentally switching between di erent languages is tiring.

We took the di cult decision to standardise on Go. The largest and most active service used
that.”

Extreme #2: the “single technology stack” approach

Let’s look at when a company is at the other extreme of this question of technology stacks;
when every team uses the same technology in a given area. This could have come about
during the early days; for example, it’s typical for companies which start with Microsoft’s
ecosystem to not diverge from the .NET world. A single technology stack could have also
come about as a result of a successful past consolidation e ort.

Whatever the reasons, we have a decently sized company where all backend engineers use
the same language and frameworks, all mobile and web engineers do the same, as do other
disciplines.

The bene ts of this setup are pretty great and are the polar opposite of the downsides in an
‘anything goes’ approach.

● Working across teams is straightforward. All teams use the same stack, so working
across services and teams is easy.
● Hiring is simple. Companies tend to hire for ‘X’ years of experience in the given
technology stack.
● Onboarding is easy, tech-wise. Assuming the company follows industry practices, new
hires will hit the ground running without much onboarding needed.
● Internal mobility is easy to put in place. With the same tech stack across teams,
encouraging people to move around is simple.

The Software Engineer’s Guidebook: Bonus Chapters Page 48


fi
ffi
ff
fi
ff
ff
fi
● Maintaining systems is much easier. If a team is low on people, it can ask for help
from other engineers.
● Easy to make the case for platform teams and DevEx teams. There’s a high chance
there’s already a core team making suggestions of practices to follow when using the
main technologies. Improving the developer experience is also a better-de ned
challenge, thanks to improvements to the handful of technologies in use.

There are several downsides to this approach:

● Hire from a more homogenous pool. The company is most likely to hire only people
who have spent years working on the main technology in use. This means the
company doesn’t consider people with more varied experiences, nor does it hire
those who could pick up the technology in a matter of weeks, and then utilize their
experience in other areas. This approach tends to make hires more homogenous.
● Harder to hire entrepreneurial engineers. Because the company mandates the
technology used, it’s harder to attract curious software engineers who are looking for
more autonomy and want to experiment with cutting-edge approaches. This is
especially the case for software engineers who see the tech stack as dated.
● The industry can evolve past the company. If a company is fully resistant to trialing
new technologies, it can miss onboarding to more productive technologies which get
popular for the right reasons. With every new language and framework, there is a risk
in both being an early adopter and in only considering it after late adopters nally do
so.
● The pressure to introduce new technologies. Any company hiring autonomous
software engineers will face a push to experiment with new technologies. And this
“pressure” is a good thing! However, without an outlet for these engineers to trial new
technologies, the same engineers might end up leaving for places less hesitant about
trying the latest approaches.

Supporting speci c languages and technologies

A common approach at more mature tech companies is to provide central support for a
limited set of technologies, and to encourage teams to choose these tools. While teams using
a di erent set of technologies is not banned, teams are on their own if they do so. At some
companies, teams may have to justify not using the centrally supported set of languages and
frameworks.

This is the approach companies with Developer Experience teams typically settle on.
Organizations like Meta, Uber or DoorDash all follow it. For example, at Uber the Developer
Experience mobile team provided support for Swift and Java on Android, while owning the
monorepo and tooling setup for each language. On iOS, teams could still use Objective C, but
they needed to take care of their own tooling support. On the backend at Uber, the languages
supported were Java and Go, with Developer Experience continually investing in tooling
improvements.

The Software Engineer’s Guidebook: Bonus Chapters Page 49


ff
fi
fi
fi
Meta follows a similar approach of listing centrally supported languages, as software
engineer Nikhil Thomas noted. The company detailed the languages that are formally
supported internally:

● Hack
● C++
● Rust
● Python

Here’s how Meta de nes the concept of ‘supported’ and ‘not supported’ languages:

● Supported means a good developer experience. Software engineers can expect to


have nice experiences with editing their code, debugging, building, deploying, core
libraries and interoperability.
● ‘Not supported’ means community support. Languages not in the ‘supported’ group
don’t come with the above guarantee. Instead, teams adopting them must take on the
burden for maintaining them, and nding/using the tools for a good developer
experience.

The company does not recommend starting new projects with unsupported languages. Of
course, teams still use languages like OCaml or Haskell, taking on the maintenance burden
themselves. It’s safe to assume that if a new language gains traction across Meta, it will likely
become easier to make a case for adding more formal support for it.

Uber is another case of how such an approach can work when consolidating a large number
of technologies. Go and Java becoming o cially supported languages was the result of
engineering leadership’s aim to consolidate the backend technologies from several
languages – Python, Node.JS, Java, Go, and others – to just one language. In the end, both
Java and Go won enough support to become o cially supported languages. Over time,
almost all new backend services were written in one of these two languages.

A ‘tech radar’ process

Putting a more formal technology adoption process in place is how some startups approach
introducing new technologies.

Sta software engineer Frank de Jonge shared the process he implemented at FinTech
startup Mollie, a European competitor to Stripe, valued at $6.5B at its last fundraising round:

“We put a process in place based on ‘tech radar.’ We started by listing the core technologies
that teams used. The process described key steps and contacts for moving a technology
through the stages of assessment → trial → general adoption. For each step, we described
what they need to provide and who to involve.”

How were engineers encouraged to take part in this? In a clever step, modifying the career
framework helped. Mollie amended its career framework, making maintenance of the ‘tech
radar’ process into an expectation of senior engineer-and-above roles.

The Software Engineer’s Guidebook: Bonus Chapters Page 50


ff
fi
fi
ffi
ffi
So, how did Mollie put the ‘tech radar’ methodology into practice? Here’s Frank’s account:

“We ended up writing a couple policies that teams needed to follow. For example: a policy on
how a sunset date needs to be given when deprecating technologies.

We managed the steps in our ‘tech radar’ methodology in a similar way to how you’d manage
action items from incidents: index, track, report, push down. We handled technology adoption
and sunsetting similarly to how one would run incident processes.

Primarily it’s about providing insights into your technology use. These insights allowed us to
make more informed decisions. We tracked deprecations, allowing us to proactively move
them out of use. New technologies would start in a trial, during which developers would see if
the technology is an actual t for the organization. Additionally, contributing to these
initiatives was recognized as a cross-team impact. Cross-team impact is recognized by the
career framework, so contributing to the initiative contributed to their performance review
and/or promo-case.

When starting out, to give people a vocabulary, I used the terminology from ThoughtWorks
TechRadar. TechRadar already de nes some of these stages like adopt, trial, assess and hold.
We added some stages of our own, like the sunset stage to stop using certain technologies. I
overlayed the TechRadar approach with a people process and that’s how our approach came
about.”

Mollie is not the only company to take inspiration from the ThoughtWorks TechRadar
approach. Autonomous trucking startup Einride – founded in 2016, $110M funding raised in
2021 – also follows a similar process. Chief software architect, Oscar Söderlund, wrote about
their tech radar process:

The Software Engineer’s Guidebook: Bonus Chapters Page 51


fi
fi
The anatomy of a tech radar. Source: Einride engineering.

● Blips: speci c technologies, all visualized on the radar. These can be languages,
frameworks, or technology processes.
● Quadrant: a collection of blips of similar types. A quadrant can be programming
languages, frameworks, ways of working, and so on.
● Ring: a collection of blips from all quadrants that are in the same phase of adoption.
Adoption phases are: 1. Holding 2. Assessing 3. Trialing 4. Using.
● Blip “direction:” depending whether a blip has moved “down” the radar, i.e. adoption
of it has decreased; or it has moved “up,” i.e. adoption has increased. When the
direction is unchanged, a di erent symbol is used.

Einride runs regular workshops at which “guilds” within the company update their respective
tech radars. A guild refers to an organization-wide forum where engineers from a discipline
share knowledge and best practices. Einride has guilds for Frontend, Backend, Data and
Autonomous Platform.

New technologies are pitched to be added to the radar during these workshops. Those
doing a pitch make the case for the gap the technology lls and why it’s an appropriate

The Software Engineer’s Guidebook: Bonus Chapters Page 52


fi
ff
fi
choice. In this workshop, existing blips can be repositioned for which Einride uses a voting
system.

As with any discussion about technology, some heated debates can be expected. Einride
uses the concept of a tiebreaker and also has put governance in place to avoid deadlocks.

I asked Oscar about how the tech radar process is going so far. Here’s what he said:

● The biggest win: having multiple tech radars and combining these tech radars with
guilds. A challenge with a single tech radar is how things can get messy when trying
to add in things like backend, frontend, data, and other niche technologies to a single
radar.
● A challenge: keeping people engaging and contributing over time. Oscar shared that
by delegating tech radars to guilds, these radars serve as decision logs. Plus, the
radar gets kept up to date during the ‘regular’ guild discussions that would happen,
anyway.
● One thing that did not work: having a public tech radar for sensitive technology.
Autonomous technologies are the bread and butter of the company. Oscar shared
how they noticed that the Autonomous Platform radar was becoming more sensitive in
regards to trade secrets, and so after a while, the group stopped maintaining it.
● One thing that worked: sharing tech radars in public and showcasing how the team
uses various technologies. With this energy boost that comes with a show-and-tell,
everyone gets more excited to keep the tech radar up-to-date.

The ‘Language Wars’

Few things arouse more emotion in software engineers than having to choose between
Language A and Language B, when the winner will be used to develop the next service, or be
adopted by a team or the whole company.

I take the term ‘language wars’ from software engineer Chris Lewis, currently at Twitter. Chris
wrote:

“The gloves really come o in the Language Wars. Few things can evoke such passion in
engineers.”

When there’s overwhelming support for one language, I’ve observed there’s less con ict,
save for a potentially vocal minority who advocate for their preferred language – which likely
doesn’t have wide support.

Democratic decision-making processes can break down when both languages have similar
levels of support, though. In such cases, any form of RFC process, voting, or type of
persuasion is likely to end up in a deadlock once the process runs its course.

So, what can you do in such a situation? Organizations usually do one of two things:

1. Use a tiebreaker to choose a winner. Someone with authority makes the decision on
which language to use. This person could be as high-rank as the CTO, or be a group

The Software Engineer’s Guidebook: Bonus Chapters Page 53


ff
fl
like the platform team which would provide the support for the language. This is how
Uber decided to use Swift for iOS development in 2016. The engineering organization
was split between the battle-tested Objective C and Swift, with the latter looking like
the future of iOS development. It was the Mobile Platform team that decided to use
Swift, and built Uber’s new mobile framework with it. Other engineering teams had no
choice but to adopt it.

The Software Engineer’s Guidebook: Bonus Chapters Page 54


2. Use both languages, going forward. The decision is made to not decide. This is how
Uber settled on supporting both Java and Go as backend development languages
around 2018, after lengthy discussion.

Try to avoid unproductive ‘language war’ arguments Choosing a language is emotional for
most software engineers; everyone tends to have a strong preference for the ones they’re
deeply familiar with.

I suggest exploring the situation before beginning a fully democratic process of choosing a
language, in which everyone has a say. In cases where most software engineers will have
input and a consensus decision is unlikely, perhaps consider running a process where
consensus isn’t required.

A good way to avoid getting bogged down in language wars, is to have a process of
introducing a new language, and promoting it to a ‘ rst class’ language within the company. In
this case, the question is not whether to use Language A or Language B, but whether to
experiment using Languages A or B at all.

Steps to consolidate to fewer technologies

Once you’ve decided to consolidate technologies, here’s some suggestions on how to deliver
it.

Steps to deliver on a process to consolidate technologies: a few suggestions.

The Software Engineer’s Guidebook: Bonus Chapters Page 55


fi
Decide on the process on how to consolidate things. In any organization where software
transparency is part of the culture, the decision on which technologies to retire should not
happen behind closed doors. Decide which process to run, who will decide, and how
software engineers can contribute. Then, announce that the process will happen and invite
people to participate.

How you run the process will depend heavily upon the technologies themselves and upon
internal organisational dynamics. A startup with 15 engineers which decides to retire one of
two web frameworks, can run a much more lightweight process. It could be as simple as the
web team agreeing with each other. The process will be more laborious at a company with
200 web engineers.

Announce how the consolidation process will proceed. After deciding on the process,
announce how it will work, and how software engineers, engineering managers and other
impacted stakeholders can participate.

Be clear about the goals of consolidation, and the cost of not doing it. Consolidation for its
own sake is not a good enough reason to invest lots of work into migrations or rewrites.

Be clear what the goals of consolidation are. Will it result in reduced costs from needing fewer
sta to maintain technologies, or cut infrastructure costs? Will it result in higher internal
mobility, shorter onboarding and faster hiring? Be clear about what the change will improve.

Aim to quantify the cost of not consolidating. What might teams and services expect if they
stick with old technology? Will they see heightened security risks, or extra workload when
updating their environments? The costs might be justi able and teams using technology
earmarked for consolidation should have a say.

O er support for learning ‘new’ technologies. Most software engineers won’t be experts on
how to best use the new language or framework you’re migrating to. Help them become
experts!

Support can encompass many things:

● In-house resources on best practices


● Pairing engineers experienced in this technology with those less experienced
● O ering training for engineers
● Dedicating time during work for engineers to study in, experiment with and learn
about the new technologies
● O ering time and budget for engineers to get up to speed on the new technologies
● Internal sessions for getting up to speed with the new language or framework

Avoid the ‘big rewrite’ trap. Once it’s been decided to ‘sunset’ a technology, should teams
start to rewrite existing systems using the new language or framework? My view is that unless
a rewrite is planned for reasons other than consolidation, then it could be an expensive
mistake. Why? The rewrite could take longer than expected, even with many engineers. Also,
the complex nature of rewrites introduces the risk of outages.

The Software Engineer’s Guidebook: Bonus Chapters Page 56


ff
ff
ff
ff
fi
Instead of mandating rewriting existing and functional systems, start by mandating that new
systems be built with the consolidated technology stack. Be mindful of unnecessary costs and
the risk of rewriting systems when this would accrue too few bene ts.

Set a reasonable end date for support of languages and frameworks. Fix a date after which
no central support will be provided for the retiring technology. This means teams which stay
on it will have the burden of maintaining the stack.

It’s tricky to set a date which satis es both the team proposing retirement and users of the
technology. Users want the date to be as distant as possible, while the team supporting
retirement wants it done without delay.

My suggestion is to sit down with the biggest users and gure out a plan that’s realistic, taking
their constraints into account.

Budget for migrations during the engineering planning process. Consolidating technology
will put additional work on teams which need to move o their current stack. This work is far
more likely to happen if the teams have it allocated during the regular planning process.

If you’re an engineering leader, make sure your teams have su cient time and bandwidth
allocated, and that engineering leadership acknowledges the e ort consolidation involves. If
you’re an engineer, push to get projects prioritized that make the consolidation happen. Read
more about the (bi-) annual planning process.

Celebrate wins along the way. Moving o a technology is an unglamorous project, together
with migrations. These projects can be complex and tricky to execute. So, as an engineering
leader, make a point of highlighting wins along the way and celebrating the contributions
which teams and individuals make.

When I was at Uber, the mobile platform team introduced a new dependency injection
framework on Android, and decided that teams needed to migrate to it, over a period of
around 6 months. To make the project more engaging, they set up Google Sheets which
broke down the modules that each group needed to migrate, and recorded the names of
engineers who completed the migrations.

This approach gami ed the migration, and several engineers stepped up to take on more
work than they were allocated. The tracking made it really easy for managers to see people
who went “above and beyond” to help this project, and to celebrate them. The mobile
platform team also spotlighted teams and people who put notably more e ort into the
migration. Thanks to a little organizing and by creating transparency, this project became fun
and not a ‘yet another framework migration.’ Read more about migrations done well.

Attrition and consolidating technologies

A common fear, when it comes to consolidating technologies, is how it will impact software
engineering attrition. There is no shortage of stories which share how, after deciding to retire
a technology, engineers quit who were experts in it.

The Software Engineer’s Guidebook: Bonus Chapters Page 57


fi
fi
ff
ff
fi
ffi
ff
fi
ff
I talked with an engineering leader at a bank which is set on consolidating Java and .NET, and
using only one. This leader predicts that whichever technology is chosen, engineers with
expertise in the other technology will leave. Software engineer Mihai Andrei shared a story
about how most native engineers left a former company after consolidating native iOS and
native Android, to Xamarin.

However, engineers leaving is not only due to consolidation of technologies. A tech lead
shared how one of their former colleagues quit because the team built a proof of concept
microservice using Go, but engineering leadership didn’t greenlight use of Go in production.

Attrition is far more likely when engineers feel they don’t have a say in decision-making. A
common thread in these stories is that engineers are likely to leave if they’re instructed to use
a technology, without the opportunity to be part of the decision to adopt it.

The company choosing to move over to Xamarin from native development is a good example.
It’s likely few native engineers would have supported that move. A bank with an even split
between Java and .NET engineers is fairly certain to see high attrition, especially if the
decision comes from above.

Having no clear process for retiring technologies or how new ones are introduced, makes it
more likely engineers will be unhappy with whatever decision is made. And if engineers see
architectural decisions coming out of a “black box” – and having no say in them – they are
more likely to quit.

If the same engineers understand how they can in uence these choices, there’s a good
chance they’ll get involved, have an in uence, and be more likely to commit to decisions they
previously wouldn’t support.

Some engineers will leave if they cannot use the technologies they’re attached to. Some
software engineers are accustomed to a particular technology and want to hone their craft
with it. These can be people at certain points in their career or those who want to go deeper
in areas such as native mobile engineering, the Microsoft stack, or other languages or
frameworks.

A heightened risk of resignations when technologies are changed, is also true for specialists.
These are experts in certain languages and frameworks. They are professionals who intend to
stay at the top of their game by working daily with these technologies.

Quitting due to a language or framework choice is rarely the full story. While I’ve observed
a few software engineers citing technology choices as the reason they resigned, in most
cases, other reasons went unspoken. Such as:

● Lack of empathy from their manager or lead on the new situation.


● No support given by managers and experienced engineers to help onboard to the
new technology.
● The engineer felt no one listened to their view about the new technology.
● The ‘why’ of changing to the new technology wasn’t shared.

The Software Engineer’s Guidebook: Bonus Chapters Page 58


fl
fl
● Several other reasons pushed this engineer to leave; the language choice was just the
nal straw.

Learning a new language or framework can be really motivating when done together with
peers, and with support from your manager. I still remember how disappointed I was to learn
that, although I was recruited as a C# expert to Microsoft to work on Skype for Xbox One, I
would have to use JavaScript for development because the C# runtime would not be ready
for the Xbox One. I was more excited about building the Skype product on the new Xbox One
than the technology I would use. So, even though I was not sold on JavaScript, I made the
most of the situation by diving into the language as deeply as I could. In the end, this journey
led me to understand many of the strange quirks of JavaScript, and also to appreciate the
dynamic nature of the language.

Attrition goes hand-in-hand with any change, and consolidating technologies can be a
major change. If a company has not previously consolidated languages and frameworks, then
the rst time it does so, the change will be big. And when major change occurs, attrition often
follows.

However, at companies where introducing and sunsetting technologies is an everyday


occurance, the change will feel smaller and the disruption of attrition is likely to be reduced.
This is why I’m warming to the idea of having in place a process for introducing and
sunsetting technologies. With it, changing technologies won’t be scary, abstract, and non-
transparent for many engineers.

Takeaways

You’ll start to feel pain points about tech stack choices, regardless of whether you start with
an ‘anything goes’ approach, or you stick doggedly to a single tech stack. As teams grow, so
do technology choices and at some point a multitude of languages and frameworks creates
more problems than it solves.

A pragmatic middle ground is to encourage using ‘standard’ technology, while not banning
experimentation with new tools. Senior engineering manager Karthik Hariharan suggests the
way to go is to create a ‘golden path tech stack,’ which is centrally supported and that
engineers love. New engineers are set up to use it as soon as they join the company, but are
free to use other tools – so long as they maintain them.

Be mindful of the type of workplace you want to build:

● Within cultures where software engineers are autonomous, this autonomy needs to
extend to the selection of tools, languages and frameworks. While having rules is
sensible, they need to bias for not blocking the use of non-standard approaches.
● Within cultures where experimentation and creativity are encouraged, you should also
encourage experimentation with a variety of tools.
● The maturity of engineering organizations is a factor. A new organizational unit is far
more likely to experiment with technologies, while a mature organization with well-
established systems will likely take fewer risks.

The Software Engineer’s Guidebook: Bonus Chapters Page 59


fi
fi
● Organizations in which software engineers aren’t allowed to make technology
decisions, will see some engineers quit for autonomy elsewhere, while those who stay
are unlikely to point out technology issues, but to toe the line instead.

Who gets to make decisions on which technologies to use, is often telling of the engineering
culture. Is it a chief architect? The CTO? Engineers on the team? The higher up the ladder
these decisions are made, the more likely it is there is less autonomy for software engineers
working at the ‘lower levels’.

Design a process for deciding which technologies to support, allowing experimentation


with new technologies. Out of all the approaches we’ve touched on, taking inspiration from
the tech radar approach is what several startups have done. I suspect that’s due to this
process’s merits, including:

● Anyone can propose trying out a new technology


● The decision to adopt a technology across the organization is made by a group
● The approach can be used both to consolidate technologies – retiring some – and to
promote other technologies for wider usage
● The approach can be implemented not just for languages and frameworks, but for
anything software engineering-related

My only cautionary advice for a group-based process such as this, is to be aware of potential
deadlocks and have an e cient way for resolving them.

The Software Engineer’s Guidebook: Bonus Chapters Page 60


ffi
Bonus #8: Becoming a Better Writer as a Software Engineer
Writing is an increasingly important skill for engineering leaders. Indeed, poor writing can
hamper career progression, above a certain level. Tactics for more clear, more frequent and
more con dent writing.

Question: I’ve observed that my writing is not up to par with my peers. How can I improve
my professional writing, as someone working in tech?

I get this question from many people: senior engineers who realize they need to level up their
writing if they are to grow to a sta position, engineering managers who feel they are not at
the same level as their peers in expressing their expertise and thoughts, and even product
managers who feel they write less e ciently than they want to.

In this chapter, we cover:

● The importance of writing for software engineers, engineering managers, and


executives.
● The process of writing well
○ Editing approaches to make your writing crisper.
○ Getting feedback on your writing.
● Improving how you write
○ Observing and copying great writing.
○ Habits to build your writing muscle.
○ Continuous learning: courses, books, and tools to boost your writing.

The Software Engineer’s Guidebook: Bonus Chapters Page 61


fi
ff
ffi
Why is writing important?

With remote work and distributed teams becoming more common, strong writing skills are a
baseline for most engineering leadership positions. In fact, writing is becoming so important
that companies like Amazon start their engineering manager screening process with a writing
exercise, as I covered in the issue Hiring Engineering Managers. Other companies that have
writing exercises during the interview process include Stripe – for Sta + engineers – and
TrueLayer, for principal engineers.

If you are a software engineer at a high-growth startup or Big Tech, the chances are you write
more words per day than you write code. Everyday writing includes:

● Commit summaries.
● Code review comments.
● Chat messages.
● Emails.
● Engineering planning documents.
● Comments on proposals, Project Requirement Documents (PRDs) or engineering
planning documents.
● Postmortems.
● Performance reviews: peer reviews, self reviews and promotion documents.

If you’re an engineering manager, a tech lead or a sta engineer, then you’ll likely be writing
even more of these:

The Software Engineer’s Guidebook: Bonus Chapters Page 62


ff
ff
● Emails and chat messages.
● Meeting agendas and meeting summaries.
● Proposals for projects, headcounts.
● Status update emails and documents for projects.
● Presentations.

Crisp writing can help accelerate your professional career. As I wrote in the article
Undervalued software engineering skills: writing well:

“It is at a larger organisation that writing becomes critical because messages reach
a bigger audience. For software engineers, writing becomes the tool to reach,
converse with and in uence engineers and teams outside their immediate peer group.
Writing becomes essential to make thoughts, tradeo s and decisions durable. Writing
things down makes these thoughts available for a wide range of people to read.
Things that should be made durable can include proposals and decisions, coding
guidelines, best practices, learnings, runbooks, debugging guides, postmortems. Even
code reviews.”

“For people to read what you write, it needs to be written well. If you grab people's
attention early on, they will keep reading and receive the message you intend to get
across. More of them will respond to it and do so with fewer misunderstandings of
what you meant. By writing well, you can scale your ability to communicate e ciently
to multiple teams, to an organisation or across the whole company. And the ability to
communicate and in uence beyond your immediate team is the essential skill for
engineers growing in seniority; from senior engineer to what organizations might call
lead, principle, sta or distinguished engineer.”

The greater the in uence of your position, the more people your writing will reach. In senior
leadership positions, writing skills are yet more important. Engineering leaders who are also
proli c writers include Andrew ‘Boz’ Bosworth the future CTO of Meta, Michael Lopp, formerly
VP of Engineering at Slack, Will Larson, CTO of Calm and Steven Sinofsky, former head of
Microsoft’s Windows division. As Steven Sinofsky writes in the article Writing is Thinking:

“Writing (and reading) really helps people if they are remote, if there is not a shared
native language, or both. Writing can be di cult for some, for sure. That is why it is
important to focus on the function, not the form. Don’t be afraid to help people
(especially as a manager) through the process of the “basics” of writing.”

The Software Engineer’s Guidebook: Bonus Chapters Page 63


fi
fl
ff
fl
fl
ffi
ff
ffi
The Process of Writing Well

When you read a piece of well-written content, know that several steps happened behind the
scenes:

● Writing: a rst draft was written. This draft captured most of the ideas and content
seen in the nal version.
● Editing: the piece was edited for readability and ease of understanding.
● Getting feedback: others might have given feedback, resulting in content changes and
more editing.

Editing Approaches
When you write a rst version of anything – from an unsent chat message all the way to a
pages-long document – it’s in its draft stage. You have captured the content. However, to
make the message as clear to readers as it is to you, the writer, you’ll probably want to edit it.

Re-reading your writing by putting yourself in the recipient’s shoes is the rst step in
editing. Before you send a chat message, re-read it, and imagine how the person on the other
side will interpret it. Is the tone right? Are the contents accurate? Are you sharing the context?

Anything beyond a sentence or two will raise questions on the structure of your writing. How
easy is it to follow? For longer writing, will your target audience have any incentive to read the
whole text?

Common editing approaches for any writing longer than a few paragraphs are these:

The Software Engineer’s Guidebook: Bonus Chapters Page 64


fi
fi
fi
fi
1. Break it into readable chunks. Avoid an o -putting wall of text that will make most readers
lose interest in reading it. Use paragraphs of a few sentences each, where each paragraph
conveys one thought.

Take the medium you use into account. If you are writing emails that could be read on
phones, consider making your paragraphs shorter, so one paragraph won’t take up the whole
screen. If you are writing a Google Doc that most of your readers will view on their laptops,
longer paragraphs are ne.

2. Remove unnecessary and distracting elements. The longer your writing, the more tiring it
is for readers to process.

It’s no coincidence that companies with strong writing cultures like Amazon are strict in
limiting all project proposals to a six-pager, often preferring one-page summaries. As I wrote
about Amazon’s planning process in the article Preparing for the annual or biannual planning:

“Writing a relatively short planning document – where the length is capped at six
pages – in practice often takes signi cantly more time than one that would not have a
length limit. Because of the length limit, every paragraph is valuable. Those writing this
document will put in lots of work to cut the unnecessary parts and make the content
crisp and easy to read.”

While writing clearly takes e ort, writing clearly and concisely is even more e ort. As French
philosopher and mathematician Blaise Pascal famously wrote in one of his letters:

“I would have written a shorter letter, but I did not have the time.”

Remove ller text that distracts from your message. For example, when writing emails, some
people try to be polite by adding things like “[I probably don’t yet fully understand the thought
process here and I apologize in advance but] could you please explain why…?” Practice polite,
but to-the-point writing in these cases. You can often shorten your message without taking
away from the tone and meaning.

3. Use shorter sentences. The longer a sentence, the harder it is to follow for your readers.
Longer sentences can also become confusing as the clauses pile up. I recommend using
Hemingway Editor to highlight parts that can be broken down.

The Software Engineer’s Guidebook: Bonus Chapters Page 65


fi
fi
ff
fi
ff
ff
Hemingway Editor helps detect hard-to-read sentences, overly complex phrases and adverbs
that can be removed. The tool is free to use on the web, and is a one-o $20 fee for Mac or
Windows as a desktop app.

4. Check grammar. Faulty grammar will leave the reader second-guessing and cause
confusion. I use Grammarly Pro, and it’s a tool I can strongly recommend, and one you could
consider expensing at work – assuming you’ll use it day-to-day.

Grammarly Pro improves grammatical correctness, writing clarity and keeping your writing
engaging.

5. Use bullet points or numbering where they make sense. Bulleted lists are a good way to
present several points. They can be used:

● In emails, proposals, tickets: almost every form of writing you’ll be doing day-to-day.

The Software Engineer’s Guidebook: Bonus Chapters Page 66


ff
● To organize your thoughts. If the individual bullet points become too long, consider
combining them in a paragraph.
● To list related items in a way that’s easier for the reader to go through than writing
paragraphs, just like this example of a bullet point list.

Numbering is another tool you can use in longer documents. This list of six editing techniques
is an example where bullet points would not work well, as each point consists of multiple
paragraphs. However, by using numbering, the reader can keep track of where we are.

6. Use bolding to make documents easy to scan. Use bold font sparingly so you can save
this styling element for key thoughts, takeaways, or asks.

As an additional suggestion, avoid bolding inside sentences like I’ve just done. It’s harder for
readers to scan things bolded inside a wall of text. Instead, re-structure your sentences so
you can bold the rst part of them.

You’ll notice my books and newsletter issues use bolding in varying quantities. This is a style I
keep iterating on, with the goal of making it easy enough to scan and nd relevant sections.

7. Use visuals, not just words. With technical documents, a screenshot or a diagram is often
worth a thousand words. So use these in the documents you create.

For inspiration, see how Cloudfare explained the reasons behind the 2021 Facebook outage,
with strong use of visuals. There is a picture for almost every paragraph of the text. Without
these pictures, the summary would have been multiple times longer, and much harder to
follow.

The Software Engineer’s Guidebook: Bonus Chapters Page 67


fi
fi
Excerpt from a well-written Cloudfare postmortem, which is easy to follow thanks to the good
use of images.

8. Value the reader’s time more than your own. The reason for editing your writing is to
make it easier for others to digest your thoughts.

If you’re sending a direct message to one person, a quick scan of what you typed should be
enough. If the same message is going out to a group chat of 100 people, take a little time to
edit it for clarity. And if we’re talking about a document read by many people in an
organization, then put in the time to make it easier for all those people to read it.

As former Amazon engineer Curtis Einsmann shares:

“3 writing tips that have worked for me:

● Simplify the language


● Start with ‘why’ then ‘how’ then ‘what’
● Value the reader’s time more than your own”

The Software Engineer’s Guidebook: Bonus Chapters Page 68


Get Feedback
After editing your writing, you might think it’s clear and crisp. But will readers agree with your
assessment?

Ask for feedback from colleagues on emails, documents and other writing for which you
could use another pair of eyes. A good approach is to share what you wrote in another
collaborative editor like Google Docs or similar.

Example of comments and suggestions using Google Docs. Collaborative editing tools with
commenting and suggestion features are excellent ways to get feedback asynchronously.

Ask people directed questions when sharing your writing. Most people will be unsure what
feedback you’re looking for, if you just ask for generic feedback. Ask speci c questions that
narrow down what help you need. Prompts you could consider include:

● “How easy to read did you nd this? What is one improvement you’d suggest?”
● “What resonated the most? And what part did you nd redundant?”
● “What would you suggest to make the takeaways more clear?”
● “What part of this document was the most confusing?”

Consider jumping on a call with your manager when writing an important document. As VP
Financial Engineering Chris Henson suggests:

“I've become favorable towards treating writing (emails, documentation, etc.) like
pair programming.

Jumping on a call with my manager as we write something usually helps to clarify


what we want to communicate, sometimes to the point of realizing work needed
rst on our end.”

You might be worried that you’ll annoy your colleagues or manager by asking too
frequently for feedback on your writing. But in my opinion, almost everyone seeks too
little feedback.

Just like there’s rarely a problem with wanting to do pair programming frequently, there’s
little harm in asking for feedback on what you write. Make notes of suggestions, and
apply those suggestions to your writing next time.

Hiring an editor is the most expensive way to get feedback, though it can be a high-
quality way to do so. The rst time I hired an editor was for my rst book, The Tech

The Software Engineer’s Guidebook: Bonus Chapters Page 69


fi
fi
fi
fi
fi
fi
Resume Inside Out. I have since worked with editors for all my books, and Dominic
Grover edits my newsletter.

As hiring an editor is an investment, most people save it for writing that goes out to larger
audiences. If you are writing a press release or content that will be published externally,
you might be able to justify hiring a copyeditor. If you have the option, I’d suggest going
for it.

There might already be editors or technical writers at your workplace. If your organization
publishes an engineering blog, there’s a fair chance they hire copyeditors to review these
articles. If this is the case, commit to writing an external-facing post, and ask for editing by
one of the in-house or contract professionals.

There are ways to get professional editing for free: write an article for a publication that
provides this editing. This includes writing for publications listed in Who Pays Technical
Writers. Some of these titles not only pay a few hundred dollars for an article, but they
often provide copyediting.

Relying on automated writing tools for feedback can dramatically improve the readability of
your writing. This is true for both Hemingway Editor and Grammarly, as well as others.

However, these tools will occasionally give suggestions that are either incorrect, or don’t t
your style. Don’t accept suggestions you disagree with, or ones you feel leave your writing in
a worse state.

The more con dent you become with your style, the more suggestions you will ignore which
the tool makes. In my case, I have learned which suggestions and rules to always ignore,
which ones to consider based on the context, and which ones to accept and incorporate into
my writing.

The Software Engineer’s Guidebook: Bonus Chapters Page 70


fi
fi
Improving How You Write

There are several ways to improve your writing skills. Let’s go through them.

Observe and Copy Great Writing


What does great writing look like? Chances are, you already know. But have you paid
conscious attention to it? Here are ways to be more deliberate in observing, saving and
copying the ingredients of great writing.

Read ction and nd books you cannot put down, which you read every sentence of. Then
revisit those books and analyse their style. How are sentences written? What made you want
to read more and not skip ahead?

People pick up non ction writing because they want to learn something. It’s because of this
that non ction that is written poorly might still become popular.

However, ction needs to draw people in to read more. Good ction uses a variety of
techniques, including storytelling style, varying the length and rhythm of sentences and
paragraphs, and many other elements.

But reading ction won’t make you a better writer by itself. However, nding great ction will
expose you to great writing which you willingly consume. I still frequently end my day picking
up a novel, reading for up to an hour before bed.

The Software Engineer’s Guidebook: Bonus Chapters Page 71


fi
fi
fi
fi
fi
fi
fi
fi
fi
Find and save some of the best professional writing you come across at work and outside
work. Collect a few of the best-written examples of:

● Emails:
○ Project status reports.
○ Project launch announcements.
○ Welcoming a new joiner.
○ Organization-wide announcements.
○ End-of-year summary.
● Engineering planning documents or proposals that are informative. Look for not just
great writing, but great use of diagrams.
● Postmortems that are to the point.
● Product speci cations like PRDs or other product planning documents that are easy to
understand.
● Tickets de ning work well.
● Discussion threads that are concise and to the point.

Analyze these written artifacts. What characteristics made them good to read?

Use some of these artifacts as templates to copy from the next time you write something
similar. For example, if you plan to put together an engineering proposal, copy the style of the
proposal that resonated most with you. After you write your document, compare it with the
inspiring one and aim to make yours equally clear as it.

Build Writing Habits


We’ve covered the theory of improving your professional writing. However, the only
meaningful way to improve is to put all of the above into practice, then rinse and repeat.

Teach yourself touch typing if you do not yet type without looking. Until typing on the
keyboard is seamless, you’ll likely write less and slower, than when you can type without
looking at the keys, and do it fast enough to not break your stream of thought. You can nd
countless courses online that help master this technique.

Put writing habits in place. Repeat activities where you make time for editing and getting
feedback. These are e cient ways to improve your writing with deliberate practice. You’ll also
want to create the habit of observing great writing, and feed these observations back to your
own improvement process.

De ne writing activities where you commit to editing and seeking feedback. You write a lot
throughout the day, and it’s not realistic to add the overhead of an involved editing and
feedback-seeking process to every document. However, you should de ne which existing or
new writing activities, you’ll pay more attention to.

For example, if you already create lots of long-form writing during your day job, de ne the
most important and most widely-circulated of it. Commit to spending more time editing these
documents and ask your manager or a peer for feedback.

The Software Engineer’s Guidebook: Bonus Chapters Page 72


fi
fi
fi
ffi
fi
fi
fi
Below are writing activities that are ideal for following a more involved editing and feedback
process:

● Start writing weekly 5-15 updates. Spend 15 minutes at the end of each week on a
report that can be read in ve minutes. Send this out to your manager and a few peers
at work. This exercise is an excellent one to do for anyone in an engineering
leadership position; I used it with great success. In reality, it will likely take more than
15 minutes to write and edit this report, but over time you’ll get better at it.
● A weekly project summary to stakeholders. Are you leading a project at work? If so,
start to put together a crisp summary of the overall progress, the risks, and what
happened since the last update. Make this update easy to read and take inspiration
from the best project update emails and documents you see in the organization.
Subscribers have access to a 🔒 Project reporting example to use as inspiration.
● Volunteer to take notes at meetings and send out summaries. Taking notes, then
spending additional time writing up a crisp summary of decisions made in a meeting,
might seem like a thankless task. True, it is time-consuming for you, but it can save
time for many others, on top of helping you get better at summarizing.
● Initiative proposals. Do you have an idea for a project you or the team should do?
Write up the idea, the problem it solves, the impact, and your ask. Edit it, and ask for
feedback to make it more clear, then send it out to the relevant group, asking for
comments. A well-written proposal is more likely to get the feedback it needs to
succeed, than one that people stop reading midway.
● Design documents. Take time editing and getting feedback on design and planning
documents you write. Use visuals to convey information more clearly. Collect great
design documents and copy structures that work for them. Ask about tools others
used to create easy-to-understand diagrams and images. Tools I recommend using for
technical visualization are Excalidraw, Lucidchart and Miro.
● Documentation. For documentation you expect more than one person to read, follow
similar advice to when writing design documents.

Continue Learning
Below are high-quality resources that can help you become a better writer.

Free online resources

● The Writing Well Handbook by Julian Shapiro. An e-book for writing non ction blogs
and books.
● Technical writing courses by Google. A collection of courses and learning resources to
improve writing technical documentation.
● The Craft of Writing E ectively: an hour and a half video from Leadership Lab. One of
the best talks about technical writing. As senior sta engineer Stefan Buck
summarized it: "Writing isn't about explaining what you think. It's about changing what
the reader thinks."

Books

The Software Engineer’s Guidebook: Bonus Chapters Page 73


ff
fi
ff
fi
● On Writing Well by William Zinsser. The classic guide to writing non ction. The book
that helped me write more concisely.
● Dreyer’s English by Benjamin Dreyer. An entertaining book to make you a better
writer.
● The Elements of Style by William Strunk Jr and E.B. White. A succinct book to help
eliminate clumsy and incorrect use of English.

Courses

● Ship 30 for 30 by Dickie Bush and Nicolas Cole. A course teaching the fundamentals
of digital writing. 8 live sessions over 30 days. Community support and accountability.
A free email course and a $499 - $699 o ering. Discount for newsletter subscribers:
use the code PRAGMATIC to get $100 o the course.
● Write of Passage by David Perrell. A course for those wanting to create high-quality
content, build a following, and connect with peers and industry leaders by publishing
online. Five weeks, 12 live sessions, 4 live writing sessions, weekly support sessions.
Runs twice per year. $4,000 to enroll, $7,000 for lifetime access.

Tools

● Hemingway Editor for help making text easier to read.


● Grammarly Pro for helping with both readability, grammar and tone.

Takeaways

Writing becomes more important as you grow more senior, regardless of where you work
within tech. For many people, their lack of writing skill becomes a blocker to progress beyond
certain levels.

This chapter was a summary of systemic approaches you can take to improve your writing
skills:

● Edit your drafts before you publish them.


● Get feedback and iterate on some of your writing.
● Observe what great writing looks like, and copy elements that make it pleasant to
read.
● Put habits in place so you work on your writing muscle on a regular basis - at the very
least, weekly.
● Continue educating yourself about writing better through resources – books and
courses – dedicated to this topic.

This chapter is packed with advice that is only worth something if you take action on it. I
suggest you make a plan on how you will improve your writing. Subscribers have access to a
🔒 Witing goals and accountability document to do so.

The Software Engineer’s Guidebook: Bonus Chapters Page 74


ff
ff
fi
Technical skills combined with writing skills are a superpower in a world that is increasingly
writing-heavy. Writing skill takes time to build and the best time to start doing so is now. Good
luck on your writing journey!

The Software Engineer’s Guidebook: Bonus Chapters Page 75


Part V: Role-model Sta and Principal Engineers
The Software Engineer’s Guidebook covers these chapters for this part:

● 21. Understanding the business


● 22. Collaboration
● 23. Software engineering
● 24. Reliable software systems
● 25. Software architecture

The two bonus chapters:

● Working with product managers as a software engineer


● Ways sta and principal engineers get stuck (and how to get unstuck)

The Software Engineer’s Guidebook: Bonus Chapters Page 76


ff
ff
Bonus #9: Working Well with Product Managers
A software engineer asks:

“As an engineering lead, I feel I should have a better working relationship with my PM.
What are things I can do to work more e ciently with them?”

Such an important topic. The highest performing and healthiest engineering teams I’ve
worked on and observed all had a strong relationship between the engineering manager and
product manager.

In this chapter, we cover:

● The pillars of a strong product / engineering manager relationship


● Engineers working well with product managers; a framework you can follow
● Tactics for sta + engineers and engineering managers

Before diving in, a story about how great engineering / product relationships take time to
build.

When I started at Uber, my team had a weekly team meeting at which we’d share engineering
updates on all our running projects. The engineering manager would share updates, and we’d
sometimes run a mini-retrospective.

A new product manager had recently joined. In her second month, she asked for a few
minutes to share product updates. She showed us product metrics and many of these metrics
were in the red, below projections. The team sat silently, not asking questions.

After the meeting, engineers felt confused and started to grumble and complain to the
engineering manager. “The PM didn’t even acknowledge that those metrics being down are
not our fault,” one said. “I felt like my work was being attacked,” another said.

What happened?

This team had never seen a product update until then. They were used to working only with
their engineering manager, focusing on the work of shipping, then moving on to the next
thing. They assumed that’s their job.

The team worked through this rough start with the new product manager. Fast forward three
months, and the team reviewed the same metrics every few weeks.

Instead of sitting silently, or feeling attacked, engineers were visibly engaged, asking
clarifying questions and o ering suggestions on what else the team could build that could
help with their team goals. And a year after this rst product metrics meeting, the team would
work on the rst feature proposed by an engineer, with a good part of the product spec
written by the engineer who proposed it.

The Software Engineer’s Guidebook: Bonus Chapters Page 77


fi
ff
ff
ffi
fi
I remember this story because it shows how disconnected product and engineering can be
from each other. It’s a reminder how as engineers, it’s easy to misinterpret the intentions of
product, even when we’re working towards the same goal.

A strong product / engineering relationship

What does a healthy engineering / product relationship look like? For me, it boils down to
these three pillars:

1. Trust and support – the foundation of everything.


2. Communication and sharing – over-communication is rarely a problem with product
and engineering. Under-communication frequently is.
3. Shared leadership – “one team, one dream.”

The Software Engineer’s Guidebook: Bonus Chapters Page 78


1. Trust and support
Trust is the basis of all strong engineering / product relationships. Gaining trust is a process
that takes time, to which your actions will contribute far more than words. Here are some
actions that can speed up building trust with your product manager.

Get to know them as a person. Hang out outside the o ce, to get to know them as a person.
Having co ee, lunch, dinner, or even going for a walk can all be great ways to talk, and not
just about work.

One of my best time investments has been to have dinner with my product manager early in
our working relationship. It worked so well that I made doing this a habit every time a new
product manager joined my team. Of course, it doesn’t have to be dinner, but spending some
hours together in a non-work setting can help establish the trust that you’ll need later. The
same way as doing an o site with a new team is a great way to bond, doing something on a
smaller scale with your product counterpart is also a good investment.

Learn about what your PM does and why. Product managers are held to di erent
expectations than an engineering team, work with a di erent set of stakeholders, and their
calendar will be very di erent from yours.

Approach your product manager’s role with curiosity and empathy. Ask them to explain what
their week looks like, where they’ll spend their time. Make it clear you’d like to understand
their world better. As you ask questions and listen to them share context, you’ll likely learn
more than you’d expect.

Have your product manager’s back. When it comes to meetings with stakeholders, planning,
internal or external events, make sure you support your PM counterpart and speak with one
voice.

Support their career growth. Learn about where they are on their career path, and what their
career goals are. You will be the peer whose feedback will carry among the most weight in
performance reviews. So don’t wait until then to give critical feedback!

Instead, help them by giving actionable feedback when you notice great things they do, as
well as suggesting areas in which they could improve or do something di erently.

Understand what their manager expects from them, for example by talking with their manager
and asking them. Find out what are the sources of pressure from above, upon your PM. Can
you help them out?

Even though you are not your PM’s manager, there’s a chance you have more people
management experience than a PM who has not managed before. Use this experience to
help coach them with their growth.

Avoid disagreeing with or surprising your PM in public. There will be occasions when new
risks emerge during projects, unplanned work comes up and pushes out timelines, or
engineering priorities change. Avoid surfacing these in public meetings in front of

The Software Engineer’s Guidebook: Bonus Chapters Page 79


ff
ff
ff
ff
ffi
ff
ff
stakeholders or the team, and putting the PM on the spot to respond straight away. Similarly,
be wary of disagreeing in front of an audience even if your product manager unknowingly
puts you on the spot.

Instead, surface new information to your product manager via private channels, and take care
of disagreements in private. Ideally, before you appear in front of an audience.

There are few ways of being certain how much trust you have, but if you both take care of
disagreements behind the scenes and speak with one voice externally, it is a very good sign
that the trust is there.

2. Communication and sharing


The main source of con ict I’ve observed between engineering and product boiled down to
miscommunication, not understanding the context of the other party, and incorrect
assumptions. As you’re working with a di erent discipline, I suggest it’s good to over-
communicate and share more, in order to avoid these common friction points.

Ask “why.” Make sure you understand why the priority of the product work is in the order it is.
If you’re not fully clear, go to the product manager and clarify. Ideally, the whole team should
share this understanding. After all, if you are missing the “why”, how will the rest of the
engineering team have this understanding?

Encourage your PM to share more with the team. In teams where engineers are more
product-minded, product managers typically share insights on the business, customer
feedback, details about the competition, o er sneak peaks of upcoming designs and much
more.

If you have a regular team meeting, it’s a good idea to hand over a part of this meeting for
more in-depth product updates and deep dives. These meetings tend to be ones in which
engineers are engaged more than usual, and they can boost energy levels in the room, all
while teaching more about the product.

A great way for product managers to make the product work visible and build empathy for it,
is to share more details on the product strategy and tactics. Summarize product planning, and
talk about OKR and KPI product meetings and discussions that are taking place. I would
always encourage PMs on my team to also add their personal take and invite questions –
which always came.

Share details about execution. Give enough context for the PM to understand what you do
and why. What are the steps of the development process that you follow? How is testing
done, and why is skipping it non-negotiable? Which engineering dependencies do you have
that slow shipping down, and why?

Many engineering managers shy away from sharing much detail because they fear the PM
getting too involved and making decisions that belong to engineering. This is where trust is
key. If you trust your PM to make decisions on the product side, they should trust you with

The Software Engineer’s Guidebook: Bonus Chapters Page 80


fl
ff
ff
engineering decisions. But just like you understand the “why” behind product decisions, you
should help them understand the “how” of engineering decisions.

Tech debt: educate and evangelize its importance. Work to address tech debt that
seemingly appears out of nowhere, is a frequent tension point between product managers
and engineering teams. Avoid surprising the product manager by bringing up this topic early.

Explain the implications of not addressing tech debt by describing the impact it will have on
product development. Will not addressing it slow down the building of products and the
output of the team? If so, by roughly how much? Will it make the product less reliable, leading
to customer complaints and churn? What is a worst-case number for this?

Reach a shared understanding of how tech debt impacts the product roadmap. Getting to this
point takes time and repetition. My advice is to start early and start small in proving the value
of not letting tech debt grow out of control.

Discuss engineering metrics and context that’s interesting for product. While some metrics
like team output and reliability likey do intersect with product, other elements might be
mysteries to the product manager. Discuss things that are relevant like build times, delays in
deploying, code freezes and new engineering dependencies or risks.

Get involved in communicating with the business and customers. Traditionally, stakeholder
management falls mostly on product over engineering. While it’s not your role to drive these
interactions, having ongoing context will help you spot issues early and it will help you step in
on the occasions when your product manager is unavailable.

Ask to be copied in on emails, or to be invited to relevant customer or stakeholder meetings.


On top of getting more context, you also bolster your product manager by lending them more
credibility, when engineering is involved in these conversations from the start.

3. Shared leadership
Well-oiled teams have a leadership that speaks with one voice. If an engineer asks a question
about strategy or tactics, both the engineering manager and the product manager should
have the same answer. If this is not the case, it leads to confusion and will likely cause con ict
down the line.

How do you avoid this situation?

Shared leadership between the engineering manager and product manager is the setup I’ve
repeatedly seen work for high-performing teams. What does shared leadership mean? If
either the EM or the PM is unavailable, the other person can step into their role on a
temporary basis. This could mean as little as representing them in a meeting with
stakeholders, all the way to lling in during a weeks-long vacation.

Shared leadership means both the EM and the PM each have enough context of the other’s
area to provide tactical guidance when needed. It also means they are aware when they are

The Software Engineer’s Guidebook: Bonus Chapters Page 81


fi
fl
not in a position to make strategic decisions on behalf of the areas they don’t own, and opt to
delay these bigger calls until the other person can make those decisions.

Clear ownership of who is responsible for what is a prerequisite for shared leadership to
work. Clarifying which areas of the work process the product manager owns, versus what falls
under the ownership of the engineering manager, is something you need to do to avoid
misunderstandings.

I suggest sitting down with the product manager and drawing out all the activities you both do
in order to ship software. Start with a blank sheet and then add areas. Once these are down,
discuss which of you is ultimately responsible for getting that work done.

What is the hando point, when something is ready for engineering to start to develop? Which
artifacts do you put in place to formalize this hando – such as product requirement
documents (PRDs), or engineering documents – and Requests for Comment (RFCs) or
Engineering Requirements Documents (ERDs), or tickets?

Here’s an example of what visualizing a process at a large tech company looks like:

An engineering team and product manager described their process like this. Do this exercise
to describe your team’s current working style. The outcome should be very di erent to the
above example.

So, are you then done with clarifying ownership after you drew up who owns which parts of
the process? Not yet! Keep iterating on this shared understanding as you’ll discover new
areas, or do so as your process changes.

The Software Engineer’s Guidebook: Bonus Chapters Page 82


ff
ff
ff
As an example of how things change at Uber, as an engineering manager I mapped out
ownership with my product manager. It turned out that we both forgot the rollout phase, and
this miss became crystal clear when shipping the next project. So we went back and altered
our shared ownership model by agreeing who owned this step in the shipping process.

Challenge each other’s decisions behind the scenes. Invite the product manager to
challenge engineering decisions by asking “why?” on anything they’re unsure of. Challenge
product decisions with similar curiosity.

How do shared leadership and challenging each other relate? If you are not fully invested in
the product decisions, you and your product counterpart won’t be able to speak publicly with
one voice. Challenging decisions and understanding why they make sense – or coming to a
di erent, better decision – help both of you be on the same page.

You are also “product”, not just the product manager. Make product problems your
problems, and help with solving them. If you say things to your engineers like “we’re waiting
on product to do X” or “product is blocking us from proceeding”, then you are not there yet.

Shared success, shared failure. I like to think of this as “one team, one dream”. Product,
engineering, and the team should celebrate successes together, because they are indeed
shared successes. Similarly, if things don’t go to plan, the blame should not lie with product
nor with engineering; it should count as the team failing, together. And the team should talk
through what they’ve learned, and which changes to make to perform better next time.

Engineers working well with product

It’s not just engineering managers who should want to have a stronger relationship with
product. Engineers who invest time and e ort to work closer with their PM are more likely to
grow into product-minded engineers. By doing so, they are more likely to help their team
focus better on product outcomes, helping both the company and their own career. Here are
some approaches that can help deepen this connection.

Ask “why”. Make sure you understand why the team is prioritizing the product work it does. If
you’re unsure, ask the product manager!

Understand how the business works. How does the company make money? What is the role
of your team in this? What is growing, what is pro table, what is not? Do your research, ask
people on the team, including your manager and the product person.

Use the product your team builds to get empathy on how it works. If the product is not
consumer-facing, still get set up on it and use it like customers would. Whenever engineers
put themselves in the customer's shoes, they often nd low hanging fruits of improvements to
make and ship later.

Build a relationship with your PM. Request to have a 1:1 catchup with them. At this session,
make it clear that you’d like to learn. O er to help them, too. Ask about pieces of work from a
product perspective that you can do, which would help the product manager or the team.

The Software Engineer’s Guidebook: Bonus Chapters Page 83


ff
ff
ff
fi
fi
Understand the product roadmap and clarify what does not make sense. Do you know
what the team will be working on for the next several months, and why on those projects, but
not others? If the answer is no, then nd the answers. Ask around to discover what work is
coming up, how it’s being prioritized and why some other projects will come later. The best
person to answer these questions is the product manager.

O er to co-write a PRD. This exercise is one of the best ways to build more empathy with
what product work is like. I especially suggest this approach after you have a product idea
that’s promising. Ask the product manager if they’d be okay with you writing a product spec
and giving you guidance on it. Tell them this exercise will help you learn about the product,
will also hopefully result in less work for the PM, and help the team.

At Uber, every time an engineer co-wrote a PRD with the product manager, they came out of
this exercise with lots of learnings on product, and a newfound product sense.

Bring engineering and product trade-o s to planning discussions. As you plan how to build
features, don’t only think about engineering trade-o s, but challenge product assumptions,
too. Would it dramatically reduce the engineering work if you relaxed a product assumption?
Or at least relax or remove the assumption from the rst version?

Get involved in interacting with users. Volunteer to take part in observing user testing, user
interviews or doing customer support – or shadowing it. Lots of engineering teams are cut o
from the customer experience. However, without knowing the experience of customers, how
can you understand what matters to them?

Tactics for sta + engineers and engineering managers

We’ve talked about approaches that can help strengthen each of the pillars of the product /
engineering relationship. There are several tactics that work well for many sta + engineers
and engineering managers and which often support these pillars of trust, communication and
shared leadership.

Regular 1:1s with your product manager. There is no better way of keeping each other up-to-
date than making time to do precisely this. When I was an engineering manager, I would have
this catch-up every week and would prioritize it as one of my most important meetings.

During this catch-up, talk about both strategy and tactics, and share the top things on your
mind. Listen to your product manager, understand their world, and help where you can. I’d
always look forward to this catch-up and regularly got more value out of it than expected.

Use PRDs and ERDs. Writing down what you’ll build, why you’ll do it (PRD) and how you’ll do
it (ERD) has consistently been the best action I’ve seen an organization do. Uber has used
PRDs, RFCs and ERDs from the very early days, and most of Big Tech and the majority of high-
growth startups ended up adopting this practice.

The biggest pushback on doing this is the perceived time that writing a document takes.
However, this time is still small in comparison to the work wasted on building the wrong thing.

The Software Engineer’s Guidebook: Bonus Chapters Page 84


ff
ff
fi
ff
ff
fi
ff
ff
With remote work becoming dominant at many places, writing down plans and distributing
them to the team is a pragmatic way to ensure the whole team stays on the same page.

Agree on who owns the rolling out of products and features and operating them. While
most teams are clear that product owns most of the planning process, and engineers own the
development phase, the next phase is often a grey area. Who owns rolling out features? Who
monitors results - product, data scientists or analysts or engineers?

Go back to the board where you sketched responsibilities and de ne clear ownership, and
clarify how you’ll go about it once development is complete. Doing this will prevent future
misunderstandings.

Mini PM / EM or PM / engineering retrospectives. Every now and then, run a short


retrospective with your product counterpart. What’s going well? What should be better? What
should you keep doing? What are things you should discontinue or change?

Regular roadmap reviews. Carve out dedicated time – either in 1:1s or in separate sessions –
to go through the roadmap. Add any new tasks that the team is working on, or that need to
be done. Talk about changing risks and dependencies.

In large organizations, a common pattern is that engineers discover a new risk, but don’t let
product know about it early enough. For example, engineers may get an email informing them
that the system for storing user data is to be decommissioned in twelve months’ time and so
they need to migrate over to a new one. Absolutely surface these kinds of risks as soon as
you discover them, so you can plan ahead, and so that the product team is aware of the non-
negotiable engineering work that needs to get done.

Talk more about outcomes and less about metrics that can be gamed. You want to build a
relationship where you can talk honestly about engineering risks that came out of nowhere
and the product/engineering/people trade-o s you can make to mitigate these. To do so, you
need to move away from focusing on proxy metrics that are disconnected from the team’s
output.

‘Story points’ and ‘story point-based velocity’ fall into this category of metrics that can easily
get disconnected from outcomes, even when no one is purposely gaming the system. While
frameworks like Scrum help teams with poor processes, they only help for so long. Most high-
performing teams in Big Tech no longer use Scrum or story points, as these approaches slow
them down.

Build a relationship with other disciplines. As an engineering manager, don’t forget to build
a bridge with other groups which your team works with. This could include data science,
design, SRE (site reliability engineering), operations and many other groups.

The Software Engineer’s Guidebook: Bonus Chapters Page 85


ff
fi
Takeaways

There’s plenty of advice in this issue on how to work better with product managers. In my
mind, it all comes down to this:

“One team, one dream.”

Do product and engineering feel like they are one and the same team? If not, gure out which
parts are missing from the pillars of trust, communication and shared leadership, and strive to
build strong bonds in those areas.

See also the article Working with Product Managers: Advice from PMs for more pointers to
build a strong relationship.

The Software Engineer’s Guidebook: Bonus Chapters Page 86


fi
Bonus #10: Ways Sta and Principal Engineers get Stuck (and
How to Get Unstuck)
Question: “I’ve joined a company as a sta engineer. I feel out of place and strangely stuck
on how to be e ective. How can I improve this situation?”

In this issue, being ‘stuck’ means you feel you’re not making as much progress in your work or
career as you should be. It may not be obvious why this is happening.

There are several ways engineers can get stuck and Camille Fournier, author of The
Manager’s Path has an excellent article describing them; from engineers being forever stuck
researching solutions, to working on side projects instead of the main ones.

I’ve observed some of the most experienced engineers on a team or in an organization to


also get stuck, but in distinctly di erent ways from most software engineers.

This chapter is written for both experienced engineers and the managers of these engineers.
As a manager, how can you spot when your sta or principal engineers are stuck, and how
can you help? As an experienced engineer, what are things you can do to get unstuck?

We cover:

● Stuck during onboarding.


● Stuck during the day-to-day.
● Stuck due to missing skills.
● Career growth is stuck.
● Stuck due to organizational factors.

For the rest of this article I’ll use “sta engineer” referring to the most senior engineer in the
organization. In your company, the exact title might be di erent; for example, tech lead,
principal engineer, or another term.

Stuck during onboarding


Onboarding is critical for all hires. However, it’s more likely there is no onboarding process
tailored for sta -and-above engineers. This is because there are often far fewer of these
engineers joining, compared to the number of entry-level, mid-level and senior engineers.

Here are ways sta engineers can get stuck during onboarding:

● Unclear role. Especially when it’s the rst sta hire in a large team or organization, the
expectations of the role can be too vague.
● Going too broad, too soon. Sta engineers are often pulled into a wide range of
meetings; from engineering discussions, all the way to management topics. However,
they might nd themselves contributing nothing meaningful, nor learning anything
worthwhile.
● Too many interruptions from the start. It’s only natural for leadership to invite sta
engineers to a large number of meetings. This is for them to learn context, with the

The Software Engineer’s Guidebook: Bonus Chapters Page 87


fi
ff
ff
ff
ff
ff
ff
ff
fi
ff
ff
ff
ff
ff
expectation that they will – over time – contribute to them. However, this can cause
too many interruptions too early, and back re by overwhelming the new hire.
● No clear deliverables during the rst months. It’s hard for sta -and-above engineers
to succeed without clear metrics for success from the rst month.
● Not building empathy with how engineering works. It almost always back res later,
when sta engineers skip the onboarding most other engineers have. This includes
shipping code to production using the standard that toolchain engineers use day-to-
day and taking part in code reviews or architecture reviews of small features. Sure, it’s
tempting to jump ahead to the large problems. But doing so often results in sta
engineers who have little empathy for how software engineering really works within
the org.
● Not growing roots on any team. Many sta roles are hired to work on cross-team
problems and initiatives. This leads to engineers having no “home” team, which
degrades their onboarding and also doesn’t help them to feel they belong on a team.
Aim for a new sta engineer to have a “home” engineering team, at least during
onboarding.
● Not clear who they really report to. It’s not uncommon to see a sta engineer report
to a director, but also have dotted lines to other managers of teams they work with.
Dotted reporting from the start is confusing and sets up sta engineers with mixed
priorities.

Going through the same onboarding as all other engineers might be tempting to bypass as a
very experienced engineer. Eric Lippert was a principal engineer at Microsoft. When he
changed jobs to join Facebook (now: Meta), he was already preallocated to a team. Still, he
found it valuable to not skip onboarding:

“When I was onboarding at Facebook I was "preallocated" to a developer tools team,


but I deliberately went through the same onboarding process as unassigned junior
developers to get a sense of how the process works, what junior developers in my
hiring cohort were experiencing, and most importantly, to nd out which pain points
existed for software developers using the developer tools that I was about to work
on.”

Actions for sta engineers who feel stuck during onboarding:

● Create your own onboarding plan and a 1, 3 and 6-month plan. Share this with your
manager and peers, and iterate on it.
● Make time and get support for engineering onboarding. Ship a few bug xes in
production.
● Find a “home” team, at least for onboarding. If your manager expects you to work
across teams from the start, try to make a case for having a “home” team, at least until
onboarding is done. This will speed up the process, grow your network, and increase
your sense of belonging.
● Say ‘no’ to too many interruptions, early on. You’ll likely get pulled into many meetings
and discussions. But stick to your onboarding plan and reject discussions that don’t
help you advance your most pressing priorities.
● Find an onboarding buddy within the organization, and a sta -or-above mentor within
the company. For the onboarding buddy, someone working on your “home” team is an

The Software Engineer’s Guidebook: Bonus Chapters Page 88


ff
ff
ff
fi
fi
ff
fi
fi
ff
ff
ff
ff
fi
fi
ff
ideal choice; and having someone less experienced might work even better, as they’ll
be closer to the coding and day-to-day work. At the same time, try to nd a sta -or-
above engineer in the company with whom you can talk through expectations, advice,
and – later on – career growth.
● Note that some organizations make a point to allocate an onboarding buddy,
especially for experienced engineers. Meta does this for principal or partner-level
engineers as part of their onboarding, on top of their Bootcamp process – which we
will explore in a newsletter issue coming in two weeks’ time.

Actions for a manager noticing a sta engineer is stuck during onboarding. Act early, and
aim to get ahead of the common reasons why engineers can get stuck:

● De ne the sta role on your team, well ahead of time. Follow the process suggested
in Hiring software engineers, write a role de nition document and share it with your
new sta hire.
● Build a 1, 3, 6-month plan with your new sta hire. This one document can help avoid
many potential onboarding pitfalls.
● Spread out the introduction meetings. Avoid the temptation to throw your new sta
engineer into all recurring meetings during the rst week.
● Designate a “home” team for them and an onboarding buddy. Don’t make the mistake
of leaving the new sta engineer without any team to onboard with.
● Coach them on how to manage their time, especially if you have a sta engineer who
has not worked at a similar sized company – or if they came from academia! They will
bene t from some coaching and encouragement to protect their time, leave space for
focused onboarding and to do their own research.

Know the impact of poor onboarding. At Uber, one of our sta engineer positions took six
months to ll. When the new sta engineer started, the leadership was excited. This engineer
was added to the majority of management meetings and assigned a large, cross-functional
project to lead.

In their rst three months, I only saw this engineer at meetings, and never observed them do
meaningful engineering work. They had no “home” team, did not complete onboarding
coding tasks, and performed no code reviews.

They tried to get involved in discussions, but were clearly missing a shared understanding of
how engineering worked, and of actual problems the team faced. They could have gotten this
context if only they had time to work as an engineer for a while.

In the end, this engineer struggled to get things done, did not build a network with
engineering, and left after six months.

I still think back on what went wrong and the answer is clear: this sta engineer had no
onboarding, no expectations set, and no space to put down roots and succeed.

The impact? A year lost as we restarted the hiring process for the role. For the next hire, we
invested in onboarding and they – nally! – lived up to expectations. Not least because they
were set up for success from day one, as the org learned from its mistake.

The Software Engineer’s Guidebook: Bonus Chapters Page 89


fi
fi
fi
ff
fi
ff
ff
ff
fi
ff
ff
fi
fi
ff
ff
fi
ff
ff
ff
Stuck during the day-to-day
Even after onboarding that goes well, it’s not uncommon for sta engineers to get stuck on
the job. Here are common patterns that cause this to happen.

Not enough clarity on the role, and no clear deliverables. Sta engineers are expected to
have a larger impact than their senior engineer peers. However, when clarity and guidance on
the role is missing, they might end up delivering smaller overall impact than some of their
senior engineer peers. Signs that this might be happening include:

● Lots of busywork. The sta engineer is attending many meetings, is adding comments
to documents, but their contribution is negligible.
● High noise, low impact. The sta engineer pulls in many people across the
organization to work on complex problems. However, these challenges have unclear
business impacts and their purpose and viability are dubious.
● Not taking initiative. The sta engineer tends to wait for others to tell them what to do.
When their plate is full, they rarely delegate upwards to their manager, or sideways to
peers.

Failing to become a multiplier. Great sta engineers help increase the output of teams
around them. When this doesn’t happen, it’s usually down to one of these three factors:

● Becoming a bottleneck without noticing. Sta engineers who become owners of a key
area, but do not share and document their knowledge, often become go-to people for
this area. However, they can get bogged down with many requests and with no way to
scale, and so have less time for more impactful work. The sta engineer can also
become a bus factor of one: when the work doesn’t progress if they are not available
for any reason.
● A fading in uence within the team and the organization. There’s a pattern of some
sta engineers having so many things on their plate that they don’t have time for
project work. They are not core members of any projects, don’t participate in code
reviews, and rarely write code. They become detached from the engineering work
and the engineering team. As such, engineers don’t seek them out for feedback or
mentorship. Even when they do appear – for example, in design documents – their
suggestions are taken less seriously by team members.
● Not mentoring other engineers. Sta engineers bring a wealth of experience and skills
to any team. One of the best ways for sta engineers to become multipliers is to
mentor other engineers. This can be done both on the go, by working with other
engineers on projects and interacting every day. It can also be done in more formal
mentorship setups. Sta engineers who do neither will nd it harder to become
multipliers.

The Software Engineer’s Guidebook: Bonus Chapters Page 90


ff
fl
ff
ff
ff
ff
ff
ff
ff
ff
fi
ff
ff
ff
Poor team dynamics. Peers in engineering leadership positions like sta engineers and
engineering managers, need to get along. If not, it leads to problems. A few examples of poor
team dynamics:

● Regular con icts between the sta engineer and other team members.
● “Too many cooks in the kitchen.” A senior-heavy team with a narrow scope that means
people regularly step on each others’ toes.
● Not getting along with peers. Sta engineers should have good enough relationships
with fellow engineers, engineering managers, product managers and business
stakeholders on the teams and projects they work on.
● Promotion elbowing. On teams where there are few “promotion-worthy” projects,
there might be elbowing between team members for who gets to work on them, and
who will lead them.

Doing exactly what worked in their last job. Many sta engineers are hired for their
experience, with the explicit expectation to own a key engineering area. At the same time,
some sta engineers will attempt to blindly pattern-match past approaches which worked well
at their previous company.

A typical example is an engineer coming from Big Tech to a scaleup and proposing to change
an engineering process to mirror that of their previous company. For example, they might
introduce a new RFC process using the same template they used in their last role.

What’s the problem with bringing best practices from other workplaces? It’s two-fold:

1. It feels top-down. Sta engineers who bring in a new process from their previous job
often do so without involving other engineers, or letting them have a say. This
approach doesn’t aid buy-in.
2. It’s ignorant of the context. If new sta engineers don’t understand the constraints of
the company, and how they di er from their old workplace, there’s a good chance the
new process will work much less well than if they tailored it to the engineering culture
of their new workplace. Take Amazon’s ORR (Operational Readiness Review) that I
cover in Inside Amazon’s Engineering Culture. It works well for Amazon. However, it
could be a useless meeting at a company without the operational rigor Amazon is
famous for.

Missing skills can obstruct sta engineers from getting things done, day-to-day. Skills that are
critical to master in order to be e cient at this level, include:

● In uencing others. Honeycomb CTO Charity Majors shares good advice on how to
build up this skill in her article On Engineers and In uence.
● Leading teams and projects. Building up this skill is most easily done by leading
projects. Most sta engineers gain this experience as they take on more responsibility.

It’s unheard of for sta engineers to not have experience of in uencing and leading others.
What is more common though, is they gained this in a di erent environment, and their past
approaches no longer work.

The Software Engineer’s Guidebook: Bonus Chapters Page 91


fl
ff
fl
ff
ff
ff
ff
ff
ffi
ff
ff
ff
fl
ff
ff
fl
ff
An “engineering culture shock” of this type typically happens when switching from a startup
to Big Tech – or vice versa – or between a non-tech company and a digital- rst company.

If you nd yourself in this situation, adapt quickly and get help through mentors, your
manager, and your peers. Entry-level engineers have no problems adapting to a new
environment and thriving there. Can you put aside your pride and adapt as quickly and
e ciently as less experienced engineers do?

Lack of focus, and attention spread too thinly. Sta engineers balancing too many small
projects without a clear focus, will nd themselves spread thinly, and could be in danger of
under-delivering on expectations. As a manager, it’s only natural to delegate all major
challenges to the most experienced engineer, but beware of overloading them.

Starting projects and moving on before they are nished, shipped and closed down, is
another sign of being spread too thinly. There are several dangers in starting a project but not
nishing it. For one, the sta engineer might not realize how some of their initial decisions did
not work out as intended. Also, sta engineers should ideally lead by example; what example
is being set by leaving a project mid-way through?

Not having regular focused time for deep work can be a sign the sta engineer is being
spread too thinly. Don’t forget sta engineers are individual contributor roles, and they should
have uninterrupted stretches of time for work.

As a sta engineer noticing you are stuck:

● Pinpoint where you are having problems and come up with ideas to solve them,
working with your manager. If you have a nagging feeling that something is not going
well, have an honest conversation; rst with yourself and then with your manager.
● Don’t let con icts brew. You’re a sta -or-above engineer, and if you have con icts,
people around you will pick up on it. Resolve these on your own if you can. If you
cannot, then ask for help from your management chain.

As a manager noticing your sta engineer is stuck during the day-to-day:

● Get feedback from people your sta engineer works with. Don’t wait until the
performance review period. Instead, reach out to stakeholders they work with, collect
actionable feedback, and share with your report. If your sta engineer doesn’t hear
the feedback they should be hearing, how can they act on it?
● Understand what your sta engineer is working on. Go through their typical week,
their calendar, their commitments and projects. Help them con rm which are priorities,
and which are not, and empower them to do fewer things, but to do those
exceptionally well.

The Software Engineer’s Guidebook: Bonus Chapters Page 92


fi
ffi
fi
ff
fl
ff
ff
ff
ff
fi
ff
ff
fi
ff
fi
ff
ff
fi
ff
fi
fl
Stuck growing career-wise
Almost no companies expect sta engineers to grow beyond this level. However, if you hire
ambitious engineers, many will want to know what is next, and how they can get there.

Not spending enough time on understanding the business can hurt sta -and-above
engineers. At this level, delivering organization-wide or company-wide business impact is
often an expectation. To do this, great engineering is rarely enough and understanding the
business is also table stakes.

Delivering organization-wide or company-wide impact requires intuition to predict upcoming


business and engineering challenges, and working ahead on these areas. This intuition
comes much easier if you understand the business and are product-minded. The easiest way
to do this is to spend time interacting with the business, and make learning that side of things
a priority.

An overly thin peer network: lack of sta -plus engineer and engineering manager (EM)
connections. Sta -and-above levels are considered as engineering leadership. E cient
engineering leaders lean on a strong internal network to get information and support for
cross-team projects and to use this network to in uence larger initiatives they have.

Many sta engineers who feel powerless to in uence other teams don’t have this network.
Sta engineers who only focus on getting the project at hand done, but don’t invest time in
getting to know other sta engineers and engineering managers across the company, nd
themselves at a disadvantage to those who do.

At Uber, I had this habit that every time I traveled to one of our other engineering o ces, I
would ask my director who are the engineers and managers whom everyone knew there. I
would then spend a day meeting these people and learning about what they did. Although
these meetings brought no direct bene t at the time, over the years they paid o handsomely.

To grow your network, aim to connect with sta engineers and managers:

● Inside your organization


● Outside your organization, but within your company
● Outside your company either locally, or in online communities like Rands Leadership
Slack or LeadDev

The lack of a career ladder for sta -and-above levels can create uncertainty, both for the
expectations of their current role and for what they need to do to reach the next level.

While sta engineers are usually more patient with career growth than early-career engineers,
don’t assume they don’t have ambitions to grow further. A career ladder that describes what
the organization needs from di erent levels can also help channel engineers’ ambitions into
solving business problems that help it grow in an outsized way.

Missing opportunities to perform at the next level. If a sta engineer is boxed into a role that
doesn’t allow them to work on initiatives that push the boundaries of their current job, they
won’t get promoted. Missing out like this happens for several reasons:

The Software Engineer’s Guidebook: Bonus Chapters Page 93


ff
ff
ff
ff
ff
ff
ff
ff
fi
ff
fl
ff
fl
ff
ff
ff
ffi
ffi
fi
● Too little scope on the team, with no support to go beyond it.
● Too much re ghting that leaves little focus for larger initiatives.
● A stalling or shrinking business. If the business stops growing, opportunities to deliver
a large impact might vanish, and the focus switch to reducing losses instead.
● A manager who does not know how to empower a sta engineer. Managers who are
used to directing engineers might nd it challenging to get along with sta engineers
needing coaching and empowerment. In unlucky cases, the sta engineer will feel
boxed in, while the manager becomes frustrated with the underwhelming results they
see from the sta engineer, and the amount of time they spend arguing with them.
● Top-down, directive approach from leadership, with insu ciently large initiatives
de ned for sta -and-above engineers. This is a more generic case of directive
managers who cannot utilize and empower sta -level engineers.

Desiring but struggling to make an outsized impact, one that could prove they are ready for
the next level. This could be down to:

● Not taking long-term or bold bets.


● Not getting buy-in for their plans from key stakeholders.
● Not persisting long enough to see projects through.
● Reorganizations disrupting long-term projects, then having to start from scratch.

Biases blocking career advancement. Biases are ingrained in humans. However, managers
who are not aware of them and do nothing to counter them are more prone to make heavily
biased performance review and promotion decisions. I wrote about common performance
review biases; what they are and how to counter them. Biases include recency, strictness,
leniency, horns, halo, similarity, central tendency and the contrasting bias.

Becoming complacent. Is there anything wrong with becoming comfortable with how things
operate, preferring to maintain the status quo that works well, and starting to feel less excited
about learning new things and experimenting with new approaches?

There’s nothing wrong with this if you’re not expecting to get outsized rewards. However,
anyone who wants outstanding performance reviews, great bonuses and promotion
opportunities will be disappointed.

At fast-growing startups and Big Tech, complacent sta -and-above engineers are rarely
rewarded with more career opportunities. There can be plenty of circumstances when
switching to a lower gear at work is the right thing to do; just manage career expectations
accordingly.

Being unhappy in the new role after a promotion. The sta engineer role is usually far more
hands-o than the senior engineer role. Some engineers only realize how di erent the two
positions are after they get the promotion. This is more often the case at companies that
promote based on potential, not based on having performed at the next level for an extended
period of time.

Those promoted into a sta role but not enjoying high-level work, will often feel trapped. They
can’t go back to the old role and can easily burn out in this new one.

The Software Engineer’s Guidebook: Bonus Chapters Page 94


fi
ff
fi
fi
ff
ff
ff
fi
ff
ff
ff
ffi
ff
ff
ff
ff
My advice is to have an honest conversation with your management chain if this is the case.
It's in everyone's interest at the company to utilize an experienced engineer to their strengths,
and not let them struggle in a role that’s not a t. There are likely plenty of projects that are
more hands-on. However, be prepared to potentially have to move teams to work on them.

As a sta engineer noticing you are stuck in your career. Pinpoint the underlying issue. Is
the problem something you can x, something your manager or the organization can x, or is
it neither? The closer you get to being the most senior engineer at the company, based on
level, the fewer career options you will have. This is by design.

The Software Engineer’s Guidebook: Bonus Chapters Page 95


ff
fi
fi
fi
Organizational issues that get sta engineers stuck
Author and software engineer Eric Lippert shares another point about the topic of
experienced engineers getting stuck. He makes the accurate observation that it’s often
organizational factors that result in many sta -and-above engineers getting stuck in their
career.

Institutionalized racism, sexism, ageism and ableism. It’s common to tiptoe around the fact
that discrimination is surprisingly common at too many companies and the best known
companies are often no exception. Discrimination can hit at all levels, including the most
senior individual contributors.

Discrimination can happen at the team-level, organization-level or company-level. Those


bene tting from discrimination might not notice it, or could turn a blind eye – even towards
obvious cases.

If you are not being discriminated against, I suggest to keep an eye open and be an ally to
those who do su er it. Being a sta -or-above engineer means your allyship and sponsorship
has an outsized impact for others.

Success being tied to o ce politics instead of business results, delighting customers or


achieving goals, becomes more common at larger companies. Observe how promotions are
decided and justi ed. How are top performing employees selected? How are special
retention bonuses or one-o bonuses awarded? Organizations at which internal in uence,
tenure and network are more important than results, quickly develop ‘whisper networks’
which prioritize politics above performance.

Figuring out how promotions are decided is easier said than done in some organizations. For
example at Microsoft, up until Satya Nadella became CEO, principal engineers shared how
their perception was that decisions on stock, bonus and promotions were made in private
meetings by managers trading political favors, instead of based on candidates’ merits. Many
companies still work like this. When they do, it’s di cult to gure out what success is really
tied to.

To nd out if an organization is heavily political before you join, consider reaching out to
people you know there, or recent leavers, and ask for their observations.

Management that focuses on fads over what is important for the business. Sadly, it’s
common enough for management to nd a measurable metric that seems like it can be a
good proxy for business results, then optimize for this metric through the company. The
problem is that almost any metric can – and will be – gamed, and the result is doing
senseless work to get this metric looking good. Examples of fads that some companies focus
on include:

● Velocity. Expecting and rewarding teams and companies which ship a certain number
of velocity points. This is typical of companies which use Scrum at scale; there’s a
reason some of the most innovative companies have moved beyond Scrum.

The Software Engineer’s Guidebook: Bonus Chapters Page 96


fi
fi
ff
fi
ffi
ff
ff
fi
ff
ff
ffi
fi
fl
● NPS (Net Promoter Score). Another popular metric to optimize is how much customers
would recommend a product. While this metric can be useful, optimizing too much for
this makes most companies forget the big picture. When I worked at Skype,
management was convinced we were headed the right way thanks to high NPS
scores. All the while, competitors like Whatsapp were gaining market share at an
accelerating pace.
● Number of pull requests feeding into performance reviews for software engineers. A
surprisingly high number of companies use metrics related to amounts of code
changes, code reviews, and other quantitative metrics, to drive performance review
and promotion decisions for software engineers. The result, predictably, is engineers
focus on writing code and avoid workarounds which would deliver the same business
result with a fraction of the work, and with no laborious code changes.

Perverse incentives driving irrational behavior. A well-known Big Tech company has several
products for the same functionality. Why? Turns out that for product managers to get
promoted to the senior product manager level, they are expected to launch a new product.
So they all do, instead of iterating on the existing product.

Promotion process expectations are very powerful drivers of behavior. At companies where
the expectation for sta -level promotions is to build and ship a complex framework, it should
be no surprise when the company is drowning in similar frameworks, many of them collecting
dust.

Stack ranking with a forced curve is another perverse incentive, whereby managers can be
incentivized to hire people who don’t fully meet the hiring bar, in order to “sacri ce” them
later as underperformers. Amazon is a whole di erent level with its internal guidance for
managers to put a certain percentage of people in an organization on Focus and PIPs,
annually.

Perverse incentives at large companies do tend to change when they start to hurt the bottom
line. For example, Microsoft followed a forced stack ranking performance management
approach for close to 20 years, but ended it in 2013.

From all that I have gathered about Microsoft’s stack ranking approach up until 2013, their
approach incentivized “promote your best performing senior engineers to the next level, then
give them a terrible review six months later to produce the quota for the bottom performers.”
This was because the curve was enforced at each level. When people got promoted to the
principal level (L65) or above, there was a small population at this level in each organization.
Come performance review time, one or two people needed to be found to be in the “below
expectations” bucket. In most cases, they were the newly promoted ones!

I talked with a principal engineer at Microsoft who left the company because of this forced
stack ranking, and because they became the “scapegoat” to be sacri ced to meet the curve.

It’s not just Microsoft changing its promotion process over the years, though; other Big Tech
rms also do the same. Uber changed performance management approaches several times
during my 4-year tenure, tweaking incentives to better match what the company was hoping
to achieve in retaining and rewarding employees.

The Software Engineer’s Guidebook: Bonus Chapters Page 97


fi
ff
ff
fi
fi
Moving goalposts midway is another typical organizational failure which still happens too
often. During the bi-annual planning, an organization may set goals for a speci c metric like
revenue. Teams prioritize these initiatives. However, midway through the cycle, leadership
changes focus to a new metric, for example customer churn. They do this in response to the
market reality changing.

At performance reviews, it’s common for management to reward those who moved the
needle of customer churn and to discount e orts made on the original target metric of
revenue generated. This behavior generates frustration among employees who feel misled,
and reduces trust with leadership.

As a senior engineering leader, keep an eye out for all of the above. They are signs of an
unhealthy organization, and one which experienced engineers are more likely to leave. You
are responsible to make sure your organization has as few of these issues as possible, and
you also have the authority to solve them. If you observe problems above your level, speak
out and suggest actions to x things.

As a manager noticing a sta engineer stuck in their career. Understand the constraints of
career advancement, and see what you can do to help. Promotion will likely stop being a
realistic goal in the short- and mid-term, so gure out ways to keep your sta engineer
motivated. This means understanding their priorities, and nding win-win opportunities for this
sta engineer to shine, while also helping the organization and the business in an outsized
way.

Don’t forget that sta -and-above engineers are some of the most experienced and capable
engineers in the organization. The fact that you have someone like this reporting to you
should allow you and your team to think boldly and create things well beyond what most
other teams could do.

The Software Engineer’s Guidebook: Bonus Chapters Page 98


ff
ff
fi
ff
fi
ff
fi
ff
fi
Takeaways
No one said sta -or-above roles are easy. Being one of the most senior engineers in an
organization is challenging by design, the same way that being one of the most senior
managers in any organization is. There are fewer paths leading ahead, and those paths are
less well mapped.

This issue has examined the ways how sta -and-above engineers often get stuck, o ering
advice both to engineers and their managers on how they might get ahead of this problem, or
get unstuck.

Still, the best you can do is to expect you will get stuck, to notice when you do, and to
make a plan for getting unstuck. It might happen during onboarding, during the day-to-day,
as you progress in your career, or even because of organizational issues beyond your control.
However, as long as you notice you’re becoming stuck, you can do something to free
yourself.

Even better is when you can predict becoming stuck, and change routes to avoid it. If you are
at the sta -or-above level, or you manage such engineers, use this issue as a refresher of the
various ways it can happen. A sta -or-above role is complex by nature, but it’s easier when
you know how things can go wrong.

The Software Engineer’s Guidebook: Bonus Chapters Page 99


ff
ff
ff
ff
ff
Closing
This marks the end of the bonus chapters for The Software Engineer’s Guidebook. As I
mentioned, these chapters all got cut in favor of what I saw as more relevant content for the
book. So if you enjoyed these bonus chapters, you’ll nd the book even more helpful.

Get The Software Engineer’s Guidebook here.

Several chapters are edited versions of issues previously published in The Pragmatic
Engineer Newsletter:

● Working at a startup vs a Big Tech (Chapter 1)


● The seniority rollercoaster (Chapter 2)
● Executing a migration (Chapter 5)
● Consolidating technologies (Chapter 7)
● Becoming a better writer as a software engineer (Chapter 8)
● Working with product managers as a software engineer (Chapter 9)
● Ways sta and principal engineers get stuck (Chapter 10)

If you enjoyed these bonus chapters, subscribe to the newsletter to get similar articles in your
inbox, weekly:

Subscribe to The Pragmatic Engineer Newsletter

Further reading
If you’ve nished The Software Engineer’s Guidebook, and these bonus chapters, here are
further reading recommendations I have:

● Additional books on software engineering: my recommendations


● The Pragmatic Engineer archives: both the latest issues, and the most popular ones

The Software Engineer’s Guidebook: Bonus Chapters Page 100


ff
fi
fi

You might also like