The Agile Echo

Choosing Wisely: When to Go Sync ⏳ and When to Go Async ⏰ in Software

The choice of whether to operate synchronously or asynchronously is dependent on a diverse set of factors, and it has a significant impact on the outcomes we generate. Sync vs async 🔄 let's explore the scenarios where each shines brightly and uncover why, more often than not, synchronous work can be the key to high-quality software development. 🚀

Cover Image for Choosing Wisely: When to Go Sync ⏳ and When to Go Async ⏰ in Software
Dan the Dev
Dan the Dev
remote-work
async-work

Introduction

We are presented with a paradox that is becoming more and more common in the dynamic world of contemporary software development: the decision between synchronous and asynchronous work. Even if the globe has seen a tremendous shift towards remote employment, it's important to remove a myth. Asynchronous work and remote work are not always related. They are two separate dimensions that are capable of coexisting or functioning separately.

When we accept remote work, we admit that the distance between us no longer limits our capacity for productive collaboration. The choice of whether to operate synchronously or asynchronously is dependent on a diverse set of factors, and it has a significant impact on the outcomes we generate.

We'll examine the circumstances in which each strategy excels in this blog article, delving into the nuances of this decision and probing the reasons why, more often than not, synchronous work emerges as the cornerstone of high-quality software development. While asynchronous work undoubtedly has advantages, we'll explain why maintaining a careful balance between the two is necessary for long-term success in the software development industry. I will also try to suggest one possible approach, in my personal take section.

So let's start this trip to learn how to make sensible software decisions about when to go sync and when to go async.

🚣 Navigate the realms of sync and async

Asynchronous (async) and synchronous (sync) are two characteristics of the way a team or organization decides to work: that decision determines the pace and flow of the work, dictating some constraints in how we handle tasks and processes within our daily work. Understanding the differences between these two paradigms is essential, particularly in a world where remote work is becoming more and more common.

What Distinguishes Sync from Async, then?

First of all, is important to notice that it is mostly communication that can be sync or async - but communication is such an important thing that this decision has an impact on the entire workflow.

Synchronous communication is the one we are used to: people are available all at the same time, working in the same hours (mostly, at least) and then they are able to communicate to each other immediately when required: response is expected in minutes because we know that we are all available together.

On the other hand, we can handle communication in an asynchronous way: people are not required to share any hours to work contemporarily and therefore are not expected to be necessarily working when someone else is working. If someone needs to communicate with someone else, the expectation is that response might even take hours, or an entire day, because the other person might work in a completely different time.

These two approaches to communication, as I already mentioned, have a huge impact on how we work: async communication implies that everyone is working mostly solo, so people are required to be autonomous, and if you need some help you will probably have to wait a lot so you should be able to find out a way to make that waiting time productive anyway.

In the last years, with remote working becoming quite normal all around the world, a lot of companies went into the path of being fully (or mostly) async in communication, and therefore also in how they work: in such organizations, work is typically handled with a feature branch for each developer, with Pull Requests at the end; you might have a single daily touchpoint with a standup that is typically just an update (and sometimes can be also async) and then work in solo the rest of the day.

I think this is a very big mistake from companies - or, at least, most companies working this way are not aware of the impact of that choice on software development, which is typically a negative impact.

🚣 Pros and cons of async work in Software Development

In general, when working remotely, async communication is a very powerful tool, that can improve employers’ lives and productivity: I won’t deny this.

Some benefits are:

  • communications are not urgent by default and they become urgent only when actually needed (when we are sync, it’s easily the reverse, which is a big mistake)

  • it’s easier to have some focus time - office context can be quite distracting, and sometimes we just need to focus

  • a better work-life balance, which is definitely the biggest pro of being able to work whenever we want

These are just some of the reasons why async communication makes a lot of sense, sometimes. But when it comes to Software Development, things are different.

If you are here, you probably heard about the Agile Manifesto: if we try to follow the Agile Manifesto we realize that async communication is an obstacle to it.

Let’s have a deeper look at the 4 values:

  • Individuals and interactions over processes and tools

    This is very reversed in async communication - every developer works on its own, with no chances of pair/mob or any feedback before the async PR - that, BTW, becomes an actual process in that context; if we go fully async, we are giving power to process and tools, instead of giving it to people

  • Working software over comprehensive documentation

    This is also the opposite when async - the reason is that we want to favor async communication as a default, so one of the consequences is that we think we should document everything at the highest level of detail possible; the problem is that documentation should be only for things that don’t change - but if you do that, it’s probably not enough for a completely async approach, so you fall into the mistake of documenting details, and either failing in keeping it updated or invest a lot of hours in doing it, with a negative ROI then compared to when and how much it will be useful

  • Customer collaboration over contract negotiation

    This becomes mostly impossible when working async - collaboration, actual collaboration, require a lot of sync communication; we cannot actually collaborate if we only communicate async via text, email, or documentation; then, it only remains to negotiate contracts, typically based on estimates and due to that, since estimates are guess and will be wrong by default, based on wrong data.

  • Responding to change by following a plan

    Finally, the 4th point also becomes mostly impossible: typically, you cannot respond to change on your own, for multiple reasons - you might not have access to the feedback autonomously, you might require some approval to change the solution away from the original plan, etc. If you have to wait hours, or days, to have feedback on changes, you will be inclined to avoid changes and follow plans without looking for faster feedback. This, again, has been proven to be non-productive in the software development world.

Basically, I don’t see a way to be Agile when working async; actually, I don’t even see how you can consider that a team: they are more like individuals that contribute to the same codebase. And if you are not Agile and do not develop your digital product as a team, you will have hard times.

🌍 The best of two worlds

What to do instead? I will dive more into my ideal approach in the “Dan’s take” section, but here are the guidelines I would follow:

  • keep async as default with company-wide non-urgent communications: unless you have to announce something urgent or very important, company-wide meetings can be easily recorded to allow people who cannot be there LIVE to see the recording later

  • keep async as default with people from different teams: this is still a good idea because communication should be non-urgent by default, and this is easier when async

  • make sync the default within the same team: given for granted that we have cross-functional teams built around our products/projects, we should favor the collaboration among the team

  • keep a couple of hours of async: it is fine to keep some async time for people to offer flexibility and freedom - for example, sticking to only 6 hours of expected sync work is a good approach

  • implement Continuous Integration: CI requires you to merge code into the main branch at least daily - this will lead the team to a more strict and frequent collaboration in a natural way

In general, remember that working together works best in most contexts, software development included - I know that working from home is a great opportunity for freedom and flexibility, but we should also consider our responsibility for the success of the company and the quality of the software.

Also, the most important thing: being async and being remote is an orthogonal decision: they are totally non-related! I’ve seen teams working async in the office, without any kind of collaboration (and no, a coffee break or lunch together is not collaboration) while I’ve been in a team working remotely pairing/mobbing/collaborating all the time.

I know what you are thinking: staying on call is tiring. I know. But while remote work is a great perk, we cannot expect it to be only pros without any cons. It is tiring, for sure, because it’s work - we can face this by learning to take proper breaks, for example.

With great powers, comes great responsibility.

Be responsible when deciding to go sync or async.

Until next time, happy coding! 🤓👩‍💻👨‍💻

Dan’s take 🙋🏻‍♂️

You know, it’s weird because for some reason we think that the approach that works great for Open Source can work also in a product/project context - but they are very different!

In Open Source, the maintainer(s) of the library receives contributions from individuals all over the world; they never know who and when someone might send a contribution, and they don’t share any objective together with them. In this context, async PR is the only way to work, allowing for different time zones and a safe way to check that the contribution is correct.

When we work in a product/project we should be working in a team.

Here are some definitions of a team:

  • a number of people who do something together as a group

  • people working together as a group in order to achieve something

  • a group of people who support a particular person or point of view

As you can see, a team works together and has shared objectives: while objectives might be clear and shared in an async context, working together is totally removed, taking inspiration from Open Source - total nonsense, in my opinion.

In a company context, whether it’s a product or project team, we should favor other things:

  • product/project success

  • company profit and safety

  • software quality to ensure profitability grows over time

  • faster feedback loop and smaller releases to favor gathering feedback from customers

With this in mind, I want to state something very strong: I think that flexibility is a great benefit, but we should never take advantage of it before considering the impact on the company. Total flexibility given from a full async can be good from some point of view, but we are not doing the best for the company: at best, we are still making money but we could be making more, but we must at least be aware of the trade-off we are taking.

What I want to say is that sometimes I feel that people only want flexibility without considering the impact of it. It’s like freedom of speech: of course, everyone has the right to say what he wants, but this is not just a right, it’s also a responsibility.

If you offend someone, you must be aware that you are responsible for that. If you talk about a topic you know nothing about, you must be aware of it. And so on.

The same is true with flexibility: if you are allowed to work from home, you should consider the impact of it: it’s not “the same:”, it’s different - let’s be honest on this, especially because most of the time is better.

What I would do, then? Well, following the principles listed above, here is how I would set up my remote organization:

  1. 6 hours of expected sync work - there are a couple of solutions that I would be testing: one could be a single time frame between 10 am and 17 am, including lunch; a different approach could be to split it into two time frames, for example, 9:30-12:30 am and 14:30-17:30 pm; both have pros and cons about lunchtime and starting time, I would probably discuss this with the team

  2. Daily standup at the beginning of the sync work - a proper standup is really useful for a collaborating team: it is not a moment of update, it is the moment when we organize the starting day; set up pairing or mobbing session when required, highlight any blocker or issue where some help might be needed, etc.

  3. Waiting time rules of thumbs - I would suggest a list of possible activities to be done when someone needs to wait for sync time; this comes from the fact that I would suggest working in single-piece flow, meaning doing one thing at a time, also meaning that if a waiting time is required, you shouldn’t start a new task; some things that are valuable can be: looking for open PR and check if an async review is enough or not, have a look at future tasks to be refined to be ready for it, or even study something (which is always a great investment)

  4. Email communication avoided (unless required, for example when talking to someone external) and Slack/Discord chat as a default communication tool: Slack or Discord are great for building a digital office setup, but I would still keep and cultivate a culture of non-urgent communication by default: response are not expected in a bunch of minutes, even if it’s a chat - in the past, for example, we had a “Pomodoro” rule: wait at least one Pomodoro (25 minutes) before pushing for a reply

  5. Continuous Integration is a must: while I love Pair/Mob, I know that not all developers love that - so, while I would suggest them as a daily practice for sure, I would leave the final choice to the team; my guidelines, anyway, would only accept practices that enables CI: no feature branches, and in general no branches longer than a day; fully automated test suite; etc.

Of course, all of those points would be discussed with the team, and the final setup and balance would be found with them because I truly believe in giving responsibility and trust. But still, these are my main ideas.

What do you think? What would you do instead? Feel free to let me know! :)


Moving from async code reviews to pairing on code review, to doing work itself together (Pair/Mob Programming) is a progression that lots of teams in our industry might benefit from experimenting with.


Go Deeper 🔎

📚 Books

📩 Newsletters

📄 Blog posts

🎙️ Podcasts

Did you enjoy this post?

Express your appreciations!

Join our Telegram channel and leave a comment!Support Learn Agile Practices

Also, if you liked this post, you will likely enjoy the other free content we offer! Discover it here: