Async is out of beta and public (Async)

Author: | Created on: Feb 5th 2019 | Last edited on: 22 days ago


We use Async on a daily basis. To this date, we've built over a dozen software projects for ourselves and our clients. Currently, we maintain two pubic repos (builderbook/builderbook and async-labs/saas) and a few private repos with the help of Async.

A few years ago, when we made the switch from Slack to Async (we used Async internally for over a year before public release), our instant reaction was: "Wow, unbelievable, this is a way more sane way to build software as a team". While using Slack, we were constantly frustrated by a flow of interruptions that fragmented our thinking and broke our coding time into small, unproductive pieces. Our goal for Async was to create a sane, unfragmented environment that keeps small teams of software engineers productive.

We released Async to the public at the end of 2018. We gradually improved Async after public release with the help of our first customers. We are proud that we've managed to keep Async simple. We use our own product and it keeps our discussions deep and focused, our coding uninterrupted, and ourselves calm and healthy.

In this article, I will share our thinking on:

  • Team communication for scientists and software engineers
  • Importance of uninterrupted discussion and execution
  • Waterfall and Agile
  • Types of teams that will benefit from using Async
  • Promise to withstand the test of time

Team communication for scientists and software engineers

Some professions require more real-time communication than others. For example, stock traders, customer support reps, and live chat sales reps must communicate "quickly" in real time to simply do their job. In contrast, some professions require "slow" asynchronous communication. Imagine scientists in research chatting and generating ideas in real time - this won't produce much progress and result in many wrong ideas.

Typically, you, as a scientist, take a few months to carry out a research experiment. Only then can you discuss results with your colleagues and finally design a new experiment. Since your colleagues are also busy working on their experiments, your discussion won't happen right away. You have to wait for your colleagues' availability, meaning you have to learn how to thrive by communicating asynchronously. Surely, there are professions that require a mix of real-time and asynchronous communication. In such cases, one communication strategy may not prevail over the other.

Software engineering, in our opinion (we were scientists and currently are software engineers), is closer to scientific research:

  • Coding a new feature takes a lot of time, similar to carrying out an experiment.
  • A team of software engineers, when they are not busy coding, finalizes discussion of a recently implemented feature and a new feature. A research group of scientists, when they are not busy doing experiments, finalizes discussion of research results and a new experiment.
  • Once the discussion about a new feature is over and the details are agreed upon, a software engineer codes the feature with deep focus, without interruption, and without the need for real-time communication. Once a new experiment is discussed and designed, a research scientist performs an experiment. To succeed, the scientist must stay focused and uninterrupted, with no interruption from real-time communication.

For professions like scientific research and software engineering, real-time communication may have a benefit when an issue is an absolute emergency. For example, a scientist may notice a dangerous chemical spill and must interrupt all other scientists in the lab to evacuate. In the case of software engineering, one engineer may notice that a web application is down and must notify the team to find the bug, fix it, and redeploy the web app.

As former scientists, we look at communication within a team of scientists or software engineers as a cycle. A cycle between discussion and execution.


Importance of uninterrupted discussion and execution

A Discussion-Execution cycle is a simple abstraction that can represent how a team of scientists work. For example, scientists discuss a hypothesis and design an experiment to test the hypothesis. Once the discussion concludes, the team assigns a team member to execute a designed experiment. That's one Discussion-Execution cycle.

Async

Once the assigned team member gets results from the experiment, it's time to discuss the results and decide if they are conclusive. This is the start of second Discussion-Execution cycle.

The same abstraction can represent the work of software engineers. A discussion may start with a customer reporting a bug or suggesting a new feature. The team then discusses this bug or feature and assigns a team member to execute it. That's one Discussion-Execution cycle for a team of software engineers.

The Discussion/Execution cycle that I mentioned above can be replaced with a better abstraction: a Hill. The Hill abstraction is highly praised and promoted by the Basecamp team launch . We think the Hill analogy is more practical for software engineering than the cycle analogy. In addition to Discussion/Uphill and Execution/Downhill stages, the Hill abstraction has 3 additional stages: Assigned, Peak, Ready to test:

Async

At the Assigned stage, the team leader assigns an issue to a team member. At Peak, the team has finalized their discussion and agreed on all specs. Once at the Peak, an issue is ready for execution. This is handy when one engineer is assigned to multiple issues - one issue can be in the Execution/Downhill stage and the rest of assigned issues can wait at the Peak. Once an issue is executed, it goes into the Ready to test stage.

From working on numerous research projects in grad school and software projects in our companies - we found that the key to productivity and sanity in any project is to have (1) discussions that are uninterrupted by execution and (2) execution that is uninterrupted by discussion. To follow this strategy, team members have limit certain behaviors, like chatting. Team members must agree to not execute during discussion and to not discuss during execution. Such a constraint may look counter productive and against common sense. However, in our experience, software projects built this way are less buggy, more thoughtful, and way faster to build.

Some of the benefits of this constraint for software development are:

  • If you are an individual software engineer, this constraint prevents you from coding until a single issue at hand is discussed and the specs are agreed upon. Starting to code without a clear understanding of the specs is a waste of time. Hence, constraint has an upside - it encourages your team to have deep and uninterrupted discussion so you can get started with coding.
  • Once you begin to execute/code, your team leader and other team members are discouraged from interrupting you. In this case, constraint allows every team member to have deep and uninterrupted work (as in Deep Work by Cal Newport).
  • The constraint adds more structure to the process: each team member learns to ask all necessary questions about specs during the initial discussion stage and to have uninterrupted coding afterwards.
  • If you are a team leader, you know exactly where every issue is in terms of stage. You clearly see which team member awaits a discussion and needs your help. You see which team member is actively coding and should not be interrupted.

It's important to note that a team member is able to initiate a new discussion while in the middle of the execution stage, but it's strongly discouraged. In our team, about 1 in every 10 issues will go back from Execution/Downhill to Discussion/Uphill and requires a second discussion.

We use the Hill abstraction to keep track of the progress on our public repo builderbook/builderbook launch . Here you can see all issues on a single Hill: https://github.com/builderbook/builderbook/issues/196 launch . Typical work in our builderbook repo is done like this:

  • GitHub user submits a bug report or an improvement.
  • Someone from our team assigns a team member (issue is labeled Assigned).
  • The assigned team member reads a comment and may or may not ask for clarifications.
  • If asking for clarification, the issue gets the Uphill label. If there is no need for clarification, the issue is labeled Peak and ready for execution.
  • Once the assigned team member begins working on the issue, it gets the Downhill/Execution label.
  • Finally, when the assigned member is done implementing the bug fix or improvement, the issue gets the Ready to test label.
  • Once tested by the community or another team member, the issue gets closed.

Waterfall and Agile

Let's look at how Waterfall and Agile launch fit into the Hill abstraction.

The key element of the Waterfall approach is in-depth planning with no flexibility to change specs. Take a look at the above Hill sketch: in the Waterfall approach, a team spends many days or weeks in the Discussion stage (Uphill), discussing and writing down specs. After that, specs are handed to team members (Peak). Engineers execute on the specs (Downhill) and are not able to go back to Discussion (Uphill).

In opposition to Waterfall, Agile embraces frequent changes in specs. In the Hill abstraction, frequent jumps between Discussion (Uphill) and Execution (Downhill) stages are common.

In Async, we don't force customers to choose one approach. Customers are free to lean towards either Waterfall or Agile within the Hill abstraction. We've been burned up by both rigid Waterfall and flexible Agile. The approach that works well for our small team is to discourage frequent jumps between Discussion/Uphill and Execution/Downhill. We encourage a thorough initial discussion followed by interrupted execution. Since we learned to work within the no interruption constraint, it's been rare for an issue to have a second discussion.


Types of teams that will benefit from adopting Async's way of working

We did not try to build Async for everyone. We learned from our previous ventures that good products often come from teams that use the product themselves. Plus, we developed Async with a small team and plan to keep that way. This is only possible if our product is focused on a certain customer and not everyone.

We currently use Async for managing 2 popular public repos (with a few hundred issues, about a dozen contributors, and a few collaborators). In addition, we use Async on 3 private repos (with a few dozen issues and a few collaborators). We find Async ideal for communication in both of these setups.

We aim for simplicity in every experience. For example, Async does not have an extensive set of features for so-called project managers/gatekeepers. We built Async for small teams. If your team is large and has multiple managers, then it might be too big for Async.


Promise to withstand the test of time

It's getting easier and easier to launch new software products, but it's becoming harder for them to last. It's probably an underestimate that hundreds of software products are launched and shut down every week.

It would be a waste of precious time to sign up and learn a product that is scheduled for shutdown soon after. I myself am risk averse and skeptical about new products. When considering a new product, I pay a lot of attention to how long the team has been in business, how the team is funded, and how long the business may last.

Since we are self-funded, we are in a position to make a promise to last. It's a joy to gradually improve and work on Async, and we believe that we will be doing it for many years to come. If for some unforeseen reason we are forced to shut down our business - we promise to open source all of Async's code and provide instructions for self-hosting.


A few notes about Articles on this website:

  • We plan to have three types of Articles on this website: Async (about Async), Building under constraints (about how we build software under healthy constraints), Technical (sharing coding bits of knowledge).
  • Content in the Articles is not static and may change over time. If any change is large enough (in the author's opinion), the author will add EDIT followed by the new content.