Take a moment and try to put yourself in the shoes of someone who’s just landed a job on a development team. You pored over page after page of job postings, looking for the perfect combination of challenging, rewarding, and remotely attainable. You fretted over every last little detail of your resume and cover letter. You spent countless hours brushing up on algorithms and data structures practice questions, determined to be prepared for anything they might throw at you in a technical interview. You made it through round after round of phone screenings, technical interviews, cultural interviews, and executive interviews. Finally, seemingly against all odds, they offered you the job and you quickly accepted before they could change their minds. Congratulations! You are officially The New Person™.
It takes about 7 seconds for the euphoria to fade and some harsh realizations to sink in:
- You probably don’t know much about what the product or project you’ll be working on actually does, and almost certainly not much about how anything actually works.
- You have no historical context for why things are the way they are, so you’ll likely be asking lots of questions. That can be hard when you’re The New Person™.
- You aren’t familiar with the team’s choices for various processes such as code reviews, version control management, release management, and countless others. You’ll be expected to pick all this stuff up quickly, as they’re essential for you to be productive at your job.
- You don’t know about random idiosyncrasies that have been adopted by the team over time, things that probably aren’t documented but people just "seem to know". You’ll likely run headfirst into these things, which isn’t great.
In short, you feel like you have no idea what you’re doing. It turns out that being The New Person™ is the worst.
We’ve all been there. For many of us, probably more than once. It’s just never much fun. Thinking back to my first job out of college, which was many years ago at a small startup company, I remember feeling all these same things. The thing I felt most strongly, however, was that I just wanted to contribute something. Anything! So that I got some sense of accomplishment, certainly, but also to show my teammates that I wasn’t just a waste of space!
These feelings of uncertainty when I was The New Person™ were hardly unique. In fact, many of the developers I’ve worked with and hired over the years have shared with me that they’ve felt these same sorts of negative emotions when they first started, and that they too felt the best way to overcome them was to just get something meaningful accomplished as quickly as possible.
One of the jobs of being a manager is to ensure that every New Person™ is set up for success to the greatest extent possible. It’s tremendously expensive to find, hire, and retain great talent, so it’s critical that all new employees get started off on the right track. Getting new employees engaged quickly makes it much more likely that they decide to stick around instead of just continuing to job hunt. This is of course a team effort, and it won’t work very well unless you have a good plan for getting the rest of the team involved.
But for the moment, if we’re saying that one of the first things to tackle is to help The New Person™ overcome these negative emotions, and that the best way to do that seems to be to help them accomplish something meaningful quickly, how can we formalize that as part of the onboarding process?
Through the years, my teams have had great success with onboarding in part by focusing on a metric called "Time to First Commit". It’s exactly as it sounds: It’s the time it takes from when The New Person™ first sits down at their desk to the time when they’ve landed their first commit to the version control system. The target you shoot for will probably vary depending on the nature of the application, your languages, frameworks, tools, and probably quite a few other factors. In general, I consider it success if The New Person™ is able to get their first commit in by the end of their first day.
This metric has a couple of properties that make it especially effective:
Time to First Commit encapsulates many different aspects of the developer experience. In order to commit code, a developer must have a fully configured development machine, security credentials assigned, source code checked out, often a task assigned in whatever issue tracking system you use, and at least some of the organization’s various SDLC polices understood at a basic level. The processes around all of these things must be optimized, at least in part, to account for this metric.
Time to First Commit is a measurable quantity, which means that it’s relatively easy to figure out where your team is at now, what a reasonable target might be, and then steps the team can take to drive towards achieving that goal. It means that as new tools are adopted and processes evolved over time, you can measure whether these things have positively or negatively impacted this metric and take the necessary steps to address any problems. For example, if a developer checks in a change that brings in some new dependency and hasn’t documented how to set it up (or better yet, automated the setup), it’s pretty likely you’ll see a regression in this metric.
At Prismatic, we’ve focused quite a bit on two key areas that have helped improve Time to First Commit.
Documentation is by no means glamorous, and if we’re honest, nobody really likes writing it or maintaining it. But everyone likes having it around. It’s especially helpful if you’re The New Person™ and you’re just trying to figure out which end is up. At Prismatic, we have gone to great lengths to document as many things as we reasonably can. The nature of the documentation generally falls into one of two categories:
Things that tend to be pretty stable get added to our wiki in Notion. These are things like:
- Our preferred Git workflow, specifically around commit messages, branch names, rebasing/merging, etc.
- How we prefer to use Clubhouse, our issue tracking system
- Various tips on troubleshooting specific issues, either related to the development environment or the Prismatic application
Things that tend to be more fluid get documented in Markdown files and committed to version control alongside the application source code, as in these cases the documentation often depends on the source code. Some examples are:
- Development environment setup guide. This is the most immediately important piece of documentation for The New Person™ on the team, so it’s given the honor of being our repository's main README. It’s the first thing they’ll see when they go to browse the repository.
- Makefile target descriptions. Makefiles are somewhat self-documenting already, but some of our targets are a bit "bespoke", so having some additional documentation around what they are for and why you might use them is very helpful.
- Instructions for running both unit and end-to-end tests
- Recommended tools, editor plug-ins, etc.
One of the nice things about having these files committed alongside the source code is that it means the documentation automatically becomes part of the code review process. We consider it a bug if an impactful change is made to the source code but not properly reflected in the documentation.
Things like setting up a new development environment, keeping dependencies updated, and managing application infrastructure changes often boil down to following a series of steps. Well, guess what? It turns out that computers are super good at following a series of steps. So make the computer do the work! The trick of course is describing the steps that they should follow. That’s where automation tooling comes in.
We’re still a pretty small team at Prismatic, so we knew that investing early on in automation would have tremendous payoff as our team continues to scale and as the application itself continues to grow in both capability and complexity. This has an additional benefit in that it significantly reduces the stress for a New Person™ joining the team, as they can be up and running with a fully configured environment in just a couple hours.
A few of the more impactful examples of automation that we’re using at Prismatic are:
- Terraform. Terraform is an incredibly powerful system and it’s what we use to manage the infrastructure for all our development, CI, demo, and production systems. Applying changes is usually as simple as running a single
- Docker. Docker provides an excellent way to programmatically describe the infrastructure for individual resources. Rather than make every developer install and manage a bunch of local instances of Postgres, Redis, etc., we have Dockerfiles that describe these resources. Updating to the latest and greatest is a simple as
git pulland then running a single
maketarget to recreate the images and redeploy.
- Git hooks. It’s a pain having to remember to run
poetry installafter pulling in somebody else’s changes. If you forget to do it right away you’ll likely run into strange runtime bugs, which is very frustrating. So again, make the computer do it! We use Husky to automatically download and install new library dependencies automatically after issuing
git pull, thereby eliminating this class of problems from the start.
- Makefiles. Sure, there are about a thousand "task runner" tools these days, but it seems that Make has seen a resurgence in popularity as of late. Why? Well, maybe because it’s pretty simple to use, installed by default basically everywhere, and it mostly Just Works™. Sure, targets can get complicated and the syntax can be weird. But in those cases you’re better off writing a separate script and calling it from your Makefile anyway. At Prismatic, dozens of the most common development tasks are exposed via a couple different Makefiles, so our developers always have a pretty consistent user interface. This is so much simpler than trying to remember what scripts are where, what arguments they take, etc.
Between having comprehensive, up-to-date documentation and automation around most common development tasks, we’ve been able to get Time to First Commit as quick as a few hours, with everyone thus far easily managing it on their first day. We will continue to pay close attention so that as our systems and processes scale in complexity, as they always seem to, we will keep that first day experience as painless as possible for The New Person™.
Do you have any methods you’ve found to be particularly helpful for improving the developer onboarding experience? Have any fun stories about when you were The New Person™? We’d love to hear about it - reach out to us on Twitter, LinkedIn, or through our website!