Three things I learned about fast and scalable software while watching software development teams
Tags: microservices
Published: 2020-02-27 12:12:44

There are  similarities between the way a team grows and how you can write scalable software. Lets apply those lessons to change our software architecture.

A software company can start with a single fullstack engineer doing everything (frontend, backend, test, build ...) but for the company to grow, it needs to add more people and to have them work together as a team to deliver quality feature at a fast pace. 

# Specialization

First of all, teams scale effectively by adding people with different skills (front-end engineers, backend engineers, test engineers, SRE, ...), who work on specific tasks and coordinate to produce fast. Specialized people are usually faster at what they do, and produce features with better quality. Also, you will have less conflicts as your team members will work on separate code bases, or modify specific parts of a shared code base.

 In the same way, **for your software to scale effectively, you have to decompose in specialized pieces**. For example, separate microservices. Each microservice can, for example, use a specific database technology or a programming language that is well suited for the features it provides. Also, different micro services will not concurrently read and write to the same database, thus avoiding locks. 

Applying [domain driven design techniques](https://dddcommunity.org/learning-ddd/what_is_ddd/) can help you separate your software in microservices.

# Asynchronous Communication

Secondly, the most effective communication is asynchronous, people send messages to colleagues and continue doing other things. They can then take decisions about how to proceed once they receive an answer. 
For example, using an issue tracker a frontend engineer can ask to the backend team to make a modification in the API. He will not wait for them to produce it before he can continue his work. He will instead have some progress on another feature while waiting for the modification. 

This is similar to the asynchronous communication in **reactive software**. Different components communicate through asynchronous messages, using the computer resources to progress on other requests while waiting for replies.

To learn more about reactive systems, have a look the the [reactive manifesto](https://www.reactivemanifesto.org/).

# Disposability

Finally different people can complete any given task if it doesn't depend on some knowledge or skill owned by a unique team member, but instead relies on information that is available to any qualified person. 
For instance, the front-end engineer can leave the team before the backend implementation he requested is ready, or he could be busy on other tasks. Because we have the documentation in the issue tracker, any other frontend team member should be able to progress with the given feature. 

This also applies to scalable software. When an instance of microservice requests data from another component to complete a task, the given task doesn't have to be completed by the same instance issuing the request. Software that runs in the cloud, or in containers managed by orchestrators like Kubernetes, should be aware of the volatility of the machines they are deployed to. New machines can be added to or removed from the cluster to reach the actual demand at any time. 

Making your software [cloud native](https://pivotal.io/cloud-native) will enable it to easily scale in your chosen runtime infrastructure.


We can learn how to scale our software by learning the many similarities between effective team work and software scalability. Have you noticed some more resemblance that you want to share with us? Please just enter a comment below and let us know any suggestion you have.