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 (
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:
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:
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.
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.
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.
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
. We think the Hill analogy is more practical for software engineering than the cycle analogy. In addition to
Execution/Downhill stages, the Hill abstraction has 3 additional stages:
Ready to test:
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:
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
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:
Uphilllabel. If there is no need for clarification, the issue is labeled
Peakand ready for execution.
Ready to testlabel.
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 (
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
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.
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.
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:
EDITfollowed by the new content.