In the modern world of software development, many teams and groups have turned to the Pull Request as a way to keep quality high and enforce standards. It’s also a natural place for testing automation, auditing, and communication.
But as many have found, the Pull Request and code review can be a bottleneck. Pull requests usually require multiple reviews before being merged; automated tests can run long; sometimes your branch needs to be 100% up-to-date with master etc. All of these things slow you down and can become sources of frustration.
Normally, this slow down isn’t enough to deter the benefits of code reviews. A few extra minutes of keeping your branch up to date or requesting another review isn’t really that bad.
Enter Mob Programming.
Mob Programming is in many ways an extension of the ideas found in Extreme Programming. Extreme Programming has collaboration as one of its central themes. Whether it’s customers working product owners, product owners working with developers, developers working with other developers, Extreme Programming works on the assumption that individuals are willing to work together and two heads are better than one. The practice of Pair Programming is a great example of this where two developers work side-by-side constantly reviewing and developing code in lock-step with one another.
Mob Programming takes this idea to its limit. Instead of having just two developers working on the same development issue or feature, throw a whole team on it! Everyone works on the same branch, pushing frequently, and keeping in constant communication about what they are working on.
You would think at the end of a few hours, the team would look something like this:
But Mob Programming can work! Our team at Bandwidth ran into a situation a few weeks ago where we had a surprise piece of work come up that we needed to get done (can’t every developer relate!). We realized
We started with two developers doing a form of pair programming. We didn’t look over each others shoulders and share keyboards and mouses (sorry Kent Beck) but we did constantly push code to a common branch, communicate about what we were changing and why and discussed solutions to problems as we faced them. At the end of a week, we had a good set of building blocks in place, but we needed to flush out a few details and add some automated testing (because the testing isn’t done until its automated!).
Lets Try This Thing!
We decided we could use some help. We grabbed a few other teammates, grabbed a conference room, and gameplanned who would work on what. Instead of doing individual pull requests for each of these tests/code changes, we decided to just work on the same branch. As a note, this branch was not master or a release branch! It was still a feature branch and that branch had to go through a pull request to get to master.
Our team went all in. We had five different developers working on different changes all at the same time, pushing commits and merging down the master branch. We had a Slack channel detailing who did what, why, what that should do next, etc. It was crazy!
But it wasn’t chaotic. Everyone was in agreement on what was happening and pushed frequently to avoid getting out of sync. Everyone kept their changes small and specific (which is what good developers should always do) to avoid unnecesarily breaking someone else. Within another week, we finished everything on time and without multiple late night sessions.
In many ways, we got lucky. We didn’t run into major roadblocks with requirements and we all had the time to dedicate 100% of our work time to the effort. But we also made a few key decisions that set us up for success. Below is a quick outline of how we did just that.
Communication is Key
In order for Mob Programming to work, you have to be in constant communication with your teammates. No one’s work is separated from another’s. And this gets heightened as you add more team members to the same branch. In fact, much of modern software development has worked to help developers work independently without breaking each constantly, so in a way, Mob Programming can feel backward. The differences are really the when and where of communication. In Mob Programming, you have to be stating exactly what, where, how, and when constantly where in the world of just pull requests and independent development efforts you can get away with less specificity and less time-sensitivity.
Our team accomplished this by a Slack channel. But it would have been even better if we were all in the same conference room (we had remote team members, so forcing all communication via a Slack channel worked well). We also had a pull request upon from our common branch to master the whole time so that we could be providing feedback as we went and have automated tests be running on every commit from any team member.
It can be tempting when working on code to making sweeping refactors when you see an improvement. In independent branches, you can get away with this a little easier and just force downstream team members to accept your changes once they go to master (which is frowned upon btw). In Mob Programming, you might have just cost someone several hours of work they were about to push.
Developers have to show thoughtful restraint in these situations and communicate if they see a place for a helpful refactor of common code and identify a quick group consensus and execute quickly. In way, I would say that Mob Programming is likely for the more mature developer who understands when the tradeoffs are worth it and not.
I think this is the most crucial element that gave our team success when doing Mob Programming. We didn’t just “go for it”. Two developers worked very closely for a little over a week creating the right abstractions, placeholders, building blocks, etc. Once the pieces were there, we could throw a lot of other developers in there to finish up a few loose ends or write tests. This meant that by the time we got to Mob status, it wasn’t a free for all: it was more like a championship sports team with each member delegating knowing the specific roles and jobs they needed to perform and then simply executing.
Without such a gameplan, I think developer opinions would have taken up much of the time and energy instead of writing code. There is always more than one way to implement a feature, and sometimes design by committee can take a long time. By having a “coaching session” of sorts between a few key developers, you can keep that process short and then assign roles to execute.
Still Do a Formal Pull Request
This was really important for our team. Even though all of our changes were being reviewed by each other while working on the code, we all know that developers can get one-track minded on a solution. Having a completely different set of eyes review is an important part of keeping quality high if you have the extra people.
In our situation, this actually simplified our code a LOT and helped us identify a refactor for later on after we hit our deadline. It also helped to keep the rest of our team in the loop about what was happening the whole time instead of lots of changes at once.
Not an Ideal Workflow
After having such success with this methodology, you would think this should be adopted as the “normal” workflow for a team. That might be possible and the author of the article mentioned earlier adopted that approach. For our team, we still choose to go back to our original strategy of having a separate branch and pull request for a feature/bug since it allows the most parallel work and most of our work isn’t as intertwined as the case we applied mob programming too.
Additionally, mob programming was hard! The additional communication was hard to keep up with and we were all drained from the effort at the end of the week.
In the end, this strategy allowed us to hit our deadline, keep quality up, and become a better team via working together. We would do it again if the need arose, but we aren’t itching for it either. If you find your team in a pinch against a tight deadline with a lot of intertwined parts, give mob