In the past year, Async Labs has grown from 4 people to 14. It’s great to see such an enormous growth of our team, but this sudden expansion brought some problems with it:

#our processes weren’t scalable

#we didn’t have developer’s documentations prepared

#our tasks and schedules were ad hoc organised and other similar issue

So we found ourselves in a situation where we had to introduce finite standards for our company (for the time being, at least).

I come from an engineering background, having completed Master of Science in Computing at Faculty of Electrical Engineering and Computing. I also started working early on in my field, getting the much needed experience in the real world.

During this time, I found that developer’s process of defining and solving a task is pretty much the same as the engineering process.

Key difference is in the fact that engineers have to document each step of that process, resulting in a flow graph even before the actual tasks, while developers “just get it” and “feel [the process] in their guts”.

Here’s a graph of the engineering process:

Steps of the engineering process.

So, having that experience, when we started talking about standardisation, I found myself (again) in this flow.

1. Define the Problem

First thing we had to do was properly define what our major pain points were. As in development, this is the entry point to the task definition. We had had a couple of retrospectives previously, so most of the technical problems had already been written out: we had to define our GitFlow, backend and frontend standards and guidelines, automate some things and clean up legacy.

But this was just a part of the problem – the developer’s technical process only. We still had to talk about our internal processes around tasks, clocking and delivering high quality software.

A small digression…

In AsyncLabs we share one key mindset – solve the problem and then pick the tool. Most of us have already worked at a couple of other companies and/or are very active in the community in our area.

This brought to us a fair advantage of seeing what other companies are doing to be successful, and not just from the external viewpoint, but from the actual gutters and real experiences.

Ok, back to the main topic.

So we got together one weekend and went through our process and main problems we encountered in the last couple of months.

These are just some of them:

  • lack of metrics (time clocking, productive – non-productive hours, amount of time spent on educations, etc.)
  • lacking QC/QA process
  • Big feedback loop
  • Poorly defined tasks
  • Non-defined priorities
  • Legacy

When we listed all of our problems, we prioritised them and sorted them in an Eisenhower Matrix on a piece of paper. This was later transferred to an actual timeline and action points that needed to be done.

2. Do Research

For each task, you have to do initial research to see if the thing you are building is, or rather, will make sense.

This phase for us was really quick: we knew momentarily that we had to organise our processes.

Having in mind our experience and mindset, we also knew how and what other companies are doing, so we recapped good processes we learned from them and talked about how and which we can apply for us.

3. Specify Requirements

In dev tasks, these represent your acceptance criteria. This is the bare minimum that you have to do when you start building your solution.

So we did exactly that: we have written ourselves a list of acceptance criteria. I, personally, am a major fan of The Golden Circle (the model, not the new Kingsman movie) so we have written our acceptances as an answer to why we want to do this.

We also defined the flow of our tasks with the stages of defining a task, working on it, confirming it was done properly and finally releasing it.

Solution life cycle

And for every stage we defined our WHY:

We are flexible and adaptable to changes which is reflected through our time management and focus that arrived from good planning.

WHY for Task stage

This phase is really important because this is the entry-point for the whole company. Stating clearly why we are doing each stage is really important for the big picture and it makes it easier to get people on board with large scale changes.

4. Brainstorm, Evaluate and Choose a Solution

Now, finally the juicy part, at least for me. 😄

After we defined our problem, we started working on solutions: choosing/abandoning tools, selecting processes, defining how we communicate with clients, how we’re going to track employee satisfaction, etc.

We drew diagrams and expanded each stage from the previous phase. This gave us a bigger picture on what we are going to tackle as smaller problems. Finally, it looked like this:

Expansion of single stages in our problem lifecycle

And every single smaller problem was defined with it’s why. We then went on to how we are going to do each single element of our process.

Here are two examples:

We are doing Agile, specifically Scrum and Kanban, with all the included ceremonies.

Task > Process

Meaning, we will organise our process with these approaches. Will this mean that we will never do Waterfall? No, it just means that we are going with this direction and anything else beside this is an exception, not a rule.

We are applying Domain Driven Design to our frontend and backend.

Development > Architecture

This still doesn’t define completely what we are going to do, but it is a general overview. For example, when working with React: we can use either ContextAPI or Redux for the state management, but they will be organised in a clean way as it is described in Domain Driven Design.

After this phase we had a more detailed overview and definition for all our tasks we needed to do, along with our timeline.

Here are just some tasks we needed to do:

  • Setup project boards in TeamWork (tool that proved to be the best current solution for us, as opposed to using TeamWork, Trello and Toggl in parallel)
  • Define backend standards and architecture (create documentation)
  • Define frontend standards and architecture (create documentation)
  • Define Git Flow
  • Showcase time tracking in TeamWork
  • Clean legacy code
  • Organise education schedule
  • Do SRMs with all employees
  • Hold quarterly company meeting
  • Schedule a team building

…and many more. With a clear picture of why and how we are going to do things, we went onto actual implementation.

5. Develop and Prototype Solution

We started with solutions which were quick and easy to implement. For me, this is the equivalent of how we approach our daily tasks so that we can focus on the more difficult ones later in the day, when we have a more specific type of focus.

Our first step was organising our tasks and boards. This was fairly simple because we had to setup boards and columns on our projects, which is a really easy thing to do with TeamWork.

Then we created card templates so that we can unify how we write cards. After that, transferring important things from Trello and setting everyone up with proper timing tool so that they can clock their productive hours. With this, Trello and Toggl became obsolete for us.

Following that was actually writing out our Agile process documentation. In this phase, we organised internal knowledge base where we will have all our documentations and processes described.

Alongside that, we created educations schedule and several different schedules that will help us in growing as a team.

The next step was to start defining our development process more thoroughly: first thing was proper GitFlow, with exampled cases and potential problems we might encounter, thus expanding our knowledge base I mentioned before.

We didn’t just introduce official GitFlow or OneFlow or even Trunk Based Git, we took the best of all three and selected what will work the best for us. We also prepared git hooks for everyone and CI pipelines so that we decrease the feedback loop as much as possible.

Furthermore, we defined what Domain Driven Design means for us on the backend. The key part here is our mindset: we choose a tool that is the best for a specific problem, not the other way around.

With this in mind, we had to communicate how we are going to do this cross-platform and cross-language. Luckily for us, we were already working in such a model, so we had a lot of code examples in our projects and we knew what will work for us.

So we took existing code and prepared a whole day workshop where we went through all of our examples and discussed everything. We named this DevPizzaDays and we are hoping that we will hold these every month. 🍕😄

All this was recorded with either video or documentation. Documentation was sent to everybody to look at and discuss before we finally locked it in. We allocated time for that for each employee.

The following two days we did SRMs with each single employee where we gave and got feedback and talked about what can we, as AsyncLabs, do for our employees and explained their role in the big picture of the company. This brought us some additional pain points we immediately added to our task lists and prioritised for the future iterations.

And much more, but I don’t want to bore you with other details. 😬

5. Test solution

For developer’s task, you usually go through MergeRequest/PullRequest, where someone does a quality control of delivered code. After that (or in parallel) you are doing quality assurance of the same code: testing that it actually does what it is supposed to do.

This phase was introduced in parallel with developing every single solution. We tested clarity of documentations by having most of the people in our company reading it out. We tested our architectures on projects we were working on. We tested our agile approach in day to day card lifecycles.

And then we went on to the next phase.

6. Solution Meets Requirements/Partially or Not at All

Luckily for us, all our solutions met our requirements. Does that mean we are super smart and extremely intelligent? Not really, this just means we picked the good solutions in our current requirement space.

As time passes and the environment changes, so will our requirement space. But for now, we are doing a good job for ourselves.

7. Communicate Results

Last phase in every problem is actually showcasing the solution. For developers, that is releasing their code or reviewing it in front the product owner.

We communicated our results during the quarterly company meeting. We went over where we were and what we have done. We communicated that this is not the final form and that we still have some tasks to finish.

We communicated how we are going to approach problems that will undoubtedly appear. We transparently communicated our current position and the future of AsyncLabs.

By doing this, we got another good feedback and got everyone on the same page about the future.

Final conclusions

We’re still not done with everything. We’re still adding things and solving them. But with the previously described process we managed to successfully explain why we are doing things and implement them in a standard flow most of us are familiar with.

By being reflective on how we solve things and what we need to do to find the solution, we had a fairly simple solution space.

We managed to organise our company completely in 2 weeks, with following month of completely grasping every single detail in our new standards. And we had a clear direction during the whole journey.

So my question for all of you out there: Now that you have the engineering terminology for your gut feelings, how will you start defining your problems? 😄