Time to Breathe

In software development there is a tendency to add, add, add, change, change, change—even when the additions or changes are not of any value.

Inspired by the ideas of Minimal Viable Products and iterative software development, but forgetting the most important parts of those, we end up rapidly iterating but not really waiting or accounting for feedback.

A team usually works on a single project, pushing the development with all the velocity they can muster—and when they realize they have been pushing in the wrong direction they turn around and push in the opposite direction, once again with full force.[anecdotal]

This is wasteful. But it is also endemic of a larger problem.

Anders Enghøj and I recently launched Mærkelex, an encyclopaedia for scout badges in Denmark.

We spent a total of 5-6 man days developing before launch, including the time we spent inputting the data on badges. The actual development time, however, stretched over several weeks, alongside our full-time occupations. We launched with a very limited feature set, aiming to test our primary hypothesis: “people would use a central resource for badges in Denmark”.

Throughout the process we made only very small code changes, one at a time. We never rushed a decision. We did a lot of usability tests. Even before launch we sought serious and varied feedback.

The main functionality of the product was a search bar, functioning as the main access point for users to look up badges (by name or category).

The search bar was originally designed to appear when a user hovered the search icon. Our usability tests, however, revealed that many users expected the search bar to appear when hovering the part of the header in which it appeared. We changed the behaviour to fit the users’ expectations.

This may seem like a minor change, but it is small changes like this, caught before launch, that make for a good user experience. If we had rushed to release, then pushed onwards with more features, this oft-used (but simple) user interaction probably would not have been as nice.

A quick note on usability tests: for best results, simply observe the user; do not interact. Our tests would usually consist of telling them the website name, then simply observing their actions. If they asked “what should I do?” we would respond “what would you like to do?” — if they made “mistakes” we considered these mistakes of design, not of the user. Casual conversation after the test revealed if they had understood the purpose of the website.

The usability tests themselves were not very time consuming, due to the sparse feature set of the application (another benefit of starting small, testing a single hypothesis). They were, however, split over several days, and would not have made much sense if the feature set had changed between individual tests. We had to take a break from developing features to get this useful feedback.

Having established a habit of reacting to user pains helped us immediately after launch: we kept getting reports that we were missing certain badges, even though they were on the site. Users expected the frontpage to show all badges on the site, but it only showed the first 30. After getting a couple of these reports and trying to use the site in the way these users expected to, we implemented a very simple solution: we added a button to show all badges, found when scrolling down to the end of the badges on the frontpage.

We call this process of waiting for feedback, as well as a good idea for a solution, time to breathe.

So far, what I’ve explained is pretty much a feedback loop, with the feedback informing decisions. Leaving time to breathe, however, has more advantages than just that.

When we had built the most basic functionality we set a date for launch. It was a goal, not a limitation: we aimed to be ready for launch on that date, but we were in no way forced to launch if we weren’t ready. We also set a simple and clear goal for when we were ready: when we could run usability tests with very little user confusion. Concrete goals are a great motivator.

From the very basic prototype, we had time to move in any promising direction we found, trying to eliminate bad user experience.

Here’s the main point: while usability tests pointed out problems, the solutions we implemented were not always straight-forward. If we did not feel like we had any good solutions at hand, we would simply let the problem wait. Taking time away from a problem gives our brains time to form solutions, often solutions we would never have found if pressed to solve a problem immediately.

We embraced the creative process, the serendipity of ideas, and only implemented something when we both agreed that it seemed like a good approach to solving our problems.

Not everything we have done has resulted in finished code in the service, but everything we have done was valuable and gave us knowledge we needed to move forward. Sometimes we built prototypes, then discussed and abandoned them. We learned from them, but they were never released.

Image: collage -- an hour glass, a light bulb, other things

In most software development companies (or departments) there is a notion that we don’t have time to wait around, we don’t have time to wait for inspiration, we don’t have time to let the features sit for a while and be tested, wait for feedback, wait for good ideas.

Software teams are tasked with solving a user pain and they come up with a solution as quickly as possible because the pressure is on. They rarely take the time to figure out a good solution. This results in mediocre software at best.

Mediocre software is better than most software: it happens in the cases where user problems are actually discovered. Many software companies simply don’t wait to discover user problems. Sometimes, “problems” are solved without being confirmed problems, features are implemented just to do something and to look busy, not because they actually benefit the user or the business.

Do you actually have time to move in the wrong direction, build something useless, then undo it? It may feel good to do something but this approach is much more wasteful than the alternative (giving it time to breathe).

We don’t have time is a fallacy, an excuse used by the stressed or those under pressure. It will not lead to good software.

There are a million reasons for being pressed on time but those are a subject for another post. Suffice it to say that they will most likely be due to an unnatural approach to software development.1

Another reason for constantly moving (emphasis on motion, not direction) is the feeling of wasting resources. If our developers aren’t developing, sitting in front of their machines, what are they doing? Are they just playing pingpong? Are they just sipping coffee, gossipping, having a nap? Probably.

But that is not necessarily bad.

Playing pingpong and gossipping are not necessarily wasteful activities.

Creativity does not happen in a vacuum. Ideas arise from serendipity.2 It is in the company’s best interest to make sure developers have access to as much knowledge as possible, whether the knowledge seems related or not.

Solutions need time to form. They form in the brains of developers while they are busy doing other things, when they take time away from the problem. Especially, actually, when they sleep!3 Activities like playing pingpong and gossipping—and even napping—move the developers towards a solution much more efficiently than staring blindly at the problem.

While breaks are not inherently wasteful there is such a thing as too long breaks—but it is an edge case, only arising when developers are motivated, but choose to stay on break.

In the end it is about balance.

There might not be any clear and good paths to take in the development of the product. No matter how long the developers take breaks, read, talk, and share ideas, they might not get an idea for the current project. That’s okay: sometimes the project itself needs time to breathe, to reveal the next step.

That takes time and users. Feedback can be provoked through usability tests, and these take time. When there are no good steps it’s probably better not to take any steps.

What should the developers do with this time? We can agree that sitting around, in a situation like this, really will be wasteful. I think this can be solved through structure of the company, more specifically in the expectations about product teams.

Businesses usually have a single team focused on a single product; sometimes many teams working on a single product, but rarely a single team working on many products. This effectively eliminates cross-pollination—the sharing of ideas and knowledge across teams and products.

Some companies try to artificially emulate cross-pollination with meetings between different teams, discussing approaches. Some companies design their buildings for watercooler moments.

A better approach would be simply letting members to teams work on several projects, in different contexts, with different people. They will get to test their ideas in real environments and learn new things from working in a different problem domain. They will evaluate their technical practices as well as their development process, and efficiently share ideas across teams.

This is the effect we got while working on Mærkelex: our full-time occupations were a source for inspiration, as well as a place to discuss and test our ideas in a different context, gathering more data.

Since the launch of Mærkelex, we have had visitors every single day, reaching as many as 411 in a single day (far exceeding our expectations for this very tiny market).

Let developers breathe. The time they spend away from code is not wasted, rather it is an important part of the creative development process.

Let the software breathe, don’t rush to create. Wait for a good solution or an obvious improvement to present itself. If this leaves you with too much time, let developers work on other products.

  1. Ron Jeffries, The Nature of Software Development, 2015.
  2. Steven Johnson, Where Good Ideas Come From, 2010.
  3. Adam Grant, The surprising habits of original thinkers (talk), 2016.

I write stuff on a pretty regular basis. If enough people sign up to my newsletter, I will start letting you know when I write new stuff.


Now read this

Face-to-face Communication: a story, some thoughts

Last week, I learned a valuable lesson or two about communication. I was working remotely that Monday, specifying a new feature. I was defining a fairly advanced interface for sending graph-like data between an app and a server, and I... Continue →