Remote Ensemble Programming at Meltwater

Ensemble programming at Meltwater

Ensemble programming (also known as mob programming) is by now a well known practice for collaborative software development. As remote work becomes more common, ensembles face a new set of challenges.

This post describes some of the practices that has evolved over a few years of remote ensemble programming at Meltwater.

NB. I have chosen to use the term “ensemble” programming, rather than “mob” programming. This is partly to avoid the negative connotation the latter carries in many languages, but also because I think the word ensemble beautifully describes the concept.

A little bit of context

My team consists of five makers, who are spread out over three cities (Berlin, Boston, Gothenburg). All of us work primarily out of our homes, and we rarely meet in person. We quite frequently do greenfield projects, but also maintain a mixed stack of components, both ones we have created ourselves, and ones we have inherited from other teams.

A couple of years ago we decided to give ensemble programming a try, and it’s been a commonly used tool for us ever since.

In this article, I describe the practicalities around how we do ensemble work, the tools we use, and why we think it’s a great way to work for us.

I will not delve into the merits of ensemble programming, as there are plenty of resources available about that, but I will still outline the main motivations for us.

Why

Frequent design discussions

Design discussions are ever ongoing in our ensemble, and we usually aim at consensus for decisions. I believe this occurs naturally whenever a few humans collaborate on any task that involves design, and I think ensemble programming is a great way to harness this phenomenon.

Knowledge sharing

Ensemble programming prevents knowledge silos. We all have, more or less, the same knowledge of our code and its context.

The knowledge gained from ensemble programming is orders of magnitude more robust than that from a 30-minute demo and code walk through. Everyone is part of the design, and takes part in the reasoning process that produces the design.

Developer happiness

We enjoy programming together. Ensemble programming means we get to hang out more than we would otherwise. Since we all work remotely, this mitigates the lack of other naturally occurring social situations, such as exchanging a few words between meetings or on the way to the coffee machine.

How

The whiteboard

In order to bring structure to our work, to make sure we don’t forget things we’ve identified as needful, and to serve as a communications link between sessions, we need a shared scratchpad. This is where the whiteboard comes in. Keeping all high level things written down somewhere, and accessible to everyone, helps reduce the cognitive load.

Well, we don’t have an actual whiteboard; we have a Trello board with the columns outlined below. Trello is a kanban board service, and any such service will work well for this purpose, so long as you can create your own lanes. Failing that, just a document or a text file can work well also; before Trello, we used a Google Document as our whiteboard.

Using Trello as an ensemble programming whiteboard

Driver list

The driver list is a list with one card for each of us, plus one for break time. The top one is the current driver. We have a separate column for parking absent member cards. Whenever the driver’s rotation finishes, they pull their card to the bottom of the lane, and we rotate.

Task columns

We keep three columns for tasks: ToDo, Current task, and Done.

The granularity of tasks here vary wildly, from very small ones (basically any task that is more work than the overhead of a trello card), to quite complex tasks.

We are usually pretty rigorous about adding cards in the ToDo column, even for little things; it just helps us make sure that we don’t forget anything. It also serves the purpose of being a parking lot; whenever we encounter problems of ideas, adding them to ToDo helps us keep up the current flow, and not go off on tangents

After we finish a task, we move it from Current Task to Done. We use this column to recall what we have been up to in our standups. We arbitrarily clear it out when it gets too big.

Ongoing experiments

Experiments are the outcome of Ensemble Retros. It contains ideas to address problems that we have identified in ensemble retros. Some examples of experiments we’ve had are “Don’t duplicate tasks in ensemble board and Jira”, and “Always write tests first”.

Rotation

Keeping a proper rotation going is essential to successfully doing ensemble programming. Make sure to keep time, keep order, and to take breaks. Missing any of these will make the whole experience significantly worse.

We rotate every 15 minutes, and use the timer app cuckoo – it lets you create a shared timer for the whole team. I strongly recommend this app, it is very nifty.

How often rotations happen tends to be proportional to how much work is involved in switching drivers. If you feel like switching more often than 20 minutes causes too much overhead, then I would recommend focusing on reducing the work required to switch. In my experience, getting frequent turns at the keyboard helps keep everyone engaged and alert.

At the beginning of every rotation we revisit the Current Task on our board, to make sure that we – pardon the sports metaphor – keep our eyes on the ball. A rotation typically happens like this:

  1. The driver commits and pushes changes. We are usually quite lax with commit messages during ensemble programming. Often just “WIP”.
  2. The driver opens the board, and reads current task out loud, then pulls their own card to the bottom of the driver list column
    1. If the Break card is now on the top of the drivers list, we take a break; somewhere between 5-15 minutes, depending on what we think we need
    2. Otherwise, driver calls out the next person on the list, and reminds them to start the timer
  3. The new driver starts sharing their screen, starts timer, pulls repo changes, and work continues

Frequent breaks

Ensemble programming is pretty taxing, and making sure we do take breaks has made a big difference for us. We usually take 10 or 15-minute breaks every 3 rotations, which works out to roughly once per hour.

Personally, I’ve found that I’m less tired in the afternoon if I do physical activities during breaks. I usually either do some little chores, such as doing dishes or laundry, or just take a very short walk.

Ensemble retros

When we started out with ensemble programming, we had short and frequent retros about it. The actual frequency varied (weekly, daily) – we tried to keep the retros short, 5-10 minutes – and we use Metro Retro:

  1. We write some stickies with problems and successes
  2. We take turns sharing and briefly explaining our stickies
  3. We vote on one problem to address
  4. We come up with some ideas how to address the problem with the most votes, and choose one our two ideas
  5. Those ideas are added to our board

Daily ensemble retros using metroretro

We don’t really have a method for considering problems solved. We have been arbitrarily clearing out these ideas from the board once we think they have served their purpose.

In my experience, these small retros give a lot of value when the team is starting out with ensemble programming. As time goes on, and the team gets into a rhythm of ensemble programming, they can be rolled into the regular team retros.

If you’re a team that is just starting out with ensemble programming, I recommend doing these little retros at least weekly.

These topics are not specifically about ensemble programming, but I want to outline them anyway. I do think that they have contributed to why my team has been successful in our ensemble programming ventures.

Psychological Safety

Psychological safety is a fundamental requirement for any well functioning team, and certainly for doing ensemble programming successfully. If we are going to sit and work together, everybody must have the experience that when they speak, then their peers listen. If I make a suggestion, which the team discusses and decides to not use, then my experience should be that the idea was examined in earnest, and turned down. It was not me, as a person or as a programmer, that was rejected.

Test Driven Development

In my experience, TDD synergizes heavily with ensemble programming. When we write tests together, we discuss what our software is going to do, and our design emerges from these discussions.

After doing ensemble programming for a while, my team decided to rigorously adopt TDD, and it has worked out very well for us. I strongly recommend devoting a month or so to doing strictly TDD in your ensemble, if you aren’t already.