Make the Right Thing the Easy Thing

How to Design Systems and Processes Teams Actually Follow

Team work

it’s our jobto keep our team running

As lead developers, we’re the glue holding our teams together. We provide
support, leadership, and mentoring to our team members. Our managers and
other non-technical leadership rely on us to keep the wheels on.

When the pressure is onwe have two choices

Fix the process

Fix the problem

When deadline pressure is on and our team is struggling to keep up, we
have two options to get us across the finish line: 1) we can figure out
what’s slowing down the team and try to fix that, or 2) we can be the
rockstar developer every recruiter dreams of and single-handedly solve
the problem.

Being the team’srockstarfeels really good

It feels great to be the hero: you pull off a miracle and finish the
project on time; your team is relieved and grateful; your manager is
happy; it typically leads to public praise and potentially promotions,
raises, and other rewards.

Being the team’sauditorfeels... less good

Digging into the underlying causes of team inefficiencies isn’t typically
considered a good time. It’s hard to communicate the business value of it,
and typically management will push back if you try to focus on underlying
problems instead of putting out immediate fires. There are not usually
rewards, recognition, or even gratitude for pursuing this option. This is
not glamorous or high-profile work.

There’s just oneproblem

Rockstarsdon’t get days off

If you’re the only reason your team hits its deadlines, that makes it
pretty tough to take a vacation.

What is your code’sbus factor?

It’s common to hear developers talk about the “bus factor” — also called
the “truck number” or “lottery number” — of a given codebase. It’s
intended to point out the fragility of a project: how many people have to
get hit by a bus before no one is left that knows how it works?

That feels a little too negative and alarmist to me, though. So what about
a more positive (and realistic) term for it?

What is your code’svacationtolerance?

On any team, we need everyone to have the ability to take time off. So
instead of talking about the bus factor, talk about how easily any given
person can go on vacation. Could two people go on vacation without
stalling the rest of the team? Ideally, every team member should be pretty
effective even if the entire team took time off.

The problem withrockstars:

They become bottlenecks

They create dependent teams

They build knowledge silos

They eventually leave

If the rockstar is carrying most of the weight for a team, that means
that work bottlenecks around the rockstar. Typically, teams start to
automatically defer to the rockstar, which means there are fewer people
taking initiative; instead, they respond to pretty much everything with,
“You’d have to check with _________.” And because of that dependency, team
members allow the rockstar to become the team’s source of truth — that’s a
huge problem, because when the rockstar eventually burns out and quits (or
retires, or gets transferred or promoted), all of that knowledge goes
with them.

We need to dobetterfor our teams

We need to fix therealproblem

Yes, it’s not all that glamorous, but if we really want to create teams
that run well, we need to fix the underlying problems that created a need
for a rockstar in the first place.

We need to create aProcess

...wait, what?

What slows teams down?

Lack of confidence in ability, knowledge, or autonomy

Lack of clarity about the goal of a given project

When teams run poorly, in my experience that largely comes from people
either lacking confidence — they’re not confident they know how to do the
thing, they’re not confident they’re allowed to do the thing without
sign-off, they’re not confident that someone else on the team won’t go in
and rewrite their code later — or lacking clarity: they’re not clear on
what’s expected of them; they’re not clear on who the stakeholders are;
they’re not clear on what “done” looks like.

A good process createsconfidence& clarity

When a team feels confident, they can act without feeling like they need
to seek approval — and that’s a good thing, because the parameters for
what someone can do without approval are clearly defined in the process.
Since the goals and accountability chains are crystal clear, no one needs
to wonder where to start or what to work on next. This leads to a team of
people who trust each other because the proper guard rails are in place.
And because there’s trust, team members feel real ownership in the
projects and process: they have a voice, and that voice is being heard.
And because the process defines what is and isn’t acceptable, the whole
team can feel safe to bring up potential issues. Usually, though, a good
process means the issues get caught way earlier, before they become
huge problems. All of this leads to the kind of high-collaboration,
high-functioning environment every management consultant dreams about.

A good process createsstronger teams

No one is a bottleneck

Each dev can make decisions independently

Knowledge is shared and documented

No chaos if devs take vacation, get promoted, or quit

How can wecreatesolid processes?

A good process needs

Excellent onboarding and documentation

Ongoing internal education and training

Frequent code reviews and coaching

Comprehensive test suites

Internally consistent style and quality guidelines

A high-functioning team’s process will be so solid that new team members
are basically painting by numbers to get started. A good measuring stick
for this is whether or not you can get a new hire up and running fast
enough to have them commit non-trivial code to production on the first
day. The team should be documenting any repeatable process so it can be
quickly referenced by everyone else. This gets driven home by solid
coaching, and the best practices are enforced by comprehensive test suites
and a set of guidelines for code style and quality.

“I’ve tried this!No onewill listen!”

I know, I just said all of the worst things. Even the most
well-intentioned teams typically try and fail to adopt things like
documentation. It might work for a while, but then it gets busy, or people
get comfortable and forget, and ultimately the team’s best practices
become more theoretical than practical.

Why processesfail

Knowvsfeel

The Rider and The Elephant

Credit: Kristin Noelle
Chip and Dan Heath have written extensively about behavioral change, and a
concept they use frequently is “the elephant and the rider”. We’re all
pretty rational and capable of thinking through long-term benefits —
that’s the rider. But there’s this other set of urges that frequently
overpower our rationality in favor of instant gratification — that’s
the elephant.
This is a concept that’s explored deeply in their book, Switch,
which I’d highly recommend reading.

Make the Right ThingThe Easy Thing

Being right isn’t enough. If we could solve human problems with logic,
there wouldn’t be any problems. The rider can only take us so far; if we
want to make real, lasting change, we need to appeal to the elephant. This
means that we need to make any new processes more emotionally rewarding
than the old way of doing things.

Emotional RewardsAutomationSimplificationYak Shaving

Make the Right Thing the Easy Thing: part 1

EmotionalRewards

Less effort required to do things the new way

Immediate praise and positive feedback

Public recognition and gratitude

One of the most rewarding things is to make people more efficient — it
feels really good to do great work ahead of schedule, so we should try to
make sure that every process we introduce feels like an upgrade. Some
processes require extra work, though, so we should make sure to frequently
and immediately praise great work from the team. When someone follows the
process, reinforce that behavior by thanking them personally. Remember, it
never sucks to hear you’re doing a good job, and usually we have to live
with “no news is good news”; offer positive feedback early and often. When
there’s a team meeting or a company all-hands, recognize the team publicly
for doing good work. It’s a small effort, but it goes a long way.

“Very few things at work feel better than the validation of other people praising your contributions in public.”Marisa MorbyProduct Manager, Gatsby

We often don’t give people praise because it feels weird to compliment
people. And maybe we’re more intrinsically motivated and don’t place the
same importance on validation, but here’s the thing: telling someone they
did a good job when you see good work never hurts; not telling
someone they did a good job can potentially lead to them feeling like
they’re doing poorly. [Tell Marisa and Mike story.]

“It doesn’t matter how objectively correct your solution is; it only matters if people will use it.”

Me, just now

Make the Right Thing the Easy Thing: part 2

Automation

Set up CI/CD (e.g. Travis, Jenkins) for tests

Run and commit Prettier automatically

Use ESLint, Danger.js, etc. to catch quality issues

Automate code coverage checks

Use semantic-release for versioning and releases

Automation is a great way to hit that efficiency emotional reward. Take
something that sucks (like deploying and testing changes) and automate it.
Once the automation is in place, it’s relatively easy to extend the
automation to do more things, like automatically fix style issues, check
for known anti-patterns with ESLint, check for internal issues using
something like Danger.js, enforce code coverage standards, or even
automatically deploy new versions of your app.

Don’t fail onstyleJust use Prettier

A surefire way to undermine any automated process is to make it nitpicky.
Don’t fail a PR on something like missing semicolons or formatting; just
run Prettier and autocommit the result to the PR. If team members have to
jump through annoying hoops to appease the automations, they WILL find a
way to work around them (like prettierignore).

Tired:

Code Cops

👮‍♀️ 👮🏽‍♂️

Earlier, I talked about how it’s not glamorous to be the team’s auditor.
Most of that comes from the fact that it sucks to have to follow people
around and hassle them about things like code style, test coverage, and
other things that we all know we should be doing, but often get lazy
about. Being the team’s code cop starts to feel a lot like being a parent
nagging your kids to clean their rooms.

Wired:

Code Bots

🤖 🤖

However, if we can get a robot in there to do the nagging, it gets a lot
easier. There’s nothing emotional or judgmental about an automated
process — no one’s code gets preferential treatment, and the rules are
exactly the same for everyone, regardless of experience or title. Plus, no
one needs to be the auditor; the things the team decides are important get
checked consistently and automatically every single time someone opens a
PR. This practice alone will avoid mountains of technical debt.

Make the Right Thing the Easy Thing: part 3

Simplification

Consider onboarding and training costs of new tools

Use open source tools if a stable option exists

Write code that’s small and easy to delete

Build for now, not 5 years into the future

It can be tempting to build a project in, say, React, and then start
adding tools: Redux, Thunk, Sagas, Recompose, and so on. But each of those
tools adds extra complexity and cognitive overhead for the team. Don’t add
a tool until you’ve got a real reason. If you definitely need a tool, look
for a well-documented, stable, open source tool first; building stuff
in-house means someone internal is on the hook to document, maintain, and
support it, and that’s rarely a sustainable option for utilities. And
don’t try to predict the future; code is a relatively short-lived product,
so trying to build something “future-proof” is a bit of a fool’s errand.
Code with deletion and replacement in mind, not infinite flexibility
and scalability.

“Weigh the trade-offs and choose the thing that makes your team more productive.”

Jem YoungSenior Software Engineer, Netflix

Everything we do in our codebase has trade-offs. Jem recommends basing
each decision on what will make the team most productive, even if that
means skipping a tool that might logically be “more correct” because it’s
too complicated to easily train the rest of the team.

“Premature optimization can be a violent source of tech debt. If you have experience and know it’s the right move, great. Otherwise: keep it as simple as possible for as long as possible.”

Chris BiscardiSoftware Engineer, Honeycomb

In the spirit of trade-offs, “future-proofing” an app is making a
trade-off. Adding a ton of “maybe we’ll need this someday” options is
extra complexity now that may never actually be useful. But we also
shouldn’t completely ignore the future when designing our projects — our
job as lead developers is to find the right balance of keeping people
productive now without ending up with tomorrow’s legacy nightmare. One way
to do this is to emphasize writing easy-to-delete code: few dependencies,
small size, and no side-effects.

Make the Right Thing the Easy Thing: part 4

Yak Shaving

Limit the team’s exposure to yak shaving

Invest in your technical foundation

Create zero- or low-config dev environments

Probably the most important point, in my humble opinion, is to limit your
team’s exposure to yak-shaving, which is all the terrible busywork we have
to do before we can do our actual work. This means investing in our
tech foundation to create solid dev environments and tooling to eliminate
the need to do a ton of work just so they can start working.

Don’t make people do a bunch of work before they can start working

Yak shaving means all the work you have to do before you can start
actually working. For example, if you need to mow the lawn, but you
realize the lawn mower is out of gas, then discover that your gas can has
a hole in it, you now have to go to the hardware store, then the gas
station, all before you can even begin doing the original task.
I can’t stress enough how important it is to invest in your team’s
technical foundation. [Straw poll: how many of you lose at least an hour a
week to fighting your dev environment (e.g. build tools, local envs,
containers, deployment)?] [Tell IBM NGINX story.]

2 hrs/week × 20 devs × $75k/year$75,000burned on yak shaving

If anyone tries to argue that working on the foundation doesn’t have
anything to do with business needs, show them this math. Assuming a dev
team of 20 people and using Glassdoor info for a salary baseline, just
two hours a week of time spent on yak shaving costs $75,000 dollars.
That’s an entire additional salary wasted on tasks that aren’t actually
related to the company’s goals.

Don’t ask people to fix a mess

Another reason to focus on the foundation is that we can enforce cultural
norms through our boilerplates. If we provide a boilerplate with all the
best practices baked into it, we’re changing the psychology of how our
team interacts with our codebase. Instead of handing our team a blank
slate (or worse, a pile of spaghetti code) and then asking them to fix it
so it follows our team standards...

Set them up tosucceed

...we should work to hand them well-built, thoroughly tested starters and
boilerplates that already meet our standards. That way, all they have to
do is keep it healthy and worry about new code. This appeals to our
subconscious desire to keep nice things nice, and it helps steer the
elephant in the direction of doing things The Right Way. We’re giving them
the best possible chance of doing something awesome, demonstrated on this
slide by these gentlemen playing sportsball.