MACH stands for Microservices, API-first, Cloud-native and Headless and joins a rich family of similar acronyms from tech history such as LAMP (Linux, Apache, MySQL, PHP) or MEAN (MongoDB, ExpressJS, AngularJS, NodeJS).
MACH describes a set of high level architectural considerations but is not very prescriptive about how these are achieved, nor does it dictate any particular technologies or implementation choices.
M is for Microservices
To be honest with you, I kinda wish M didn’t stand for Microservices in MACH.
Microservices architectures can enable tremendous scale, team autonomy and release independence, but they are also complex and introduce a range of new, painful, often transient and hard-to-diagnose failure modes. (Can you tell I’ve been bitten more than a few times?)
Instead I wish M stood for “modular”, which is really what I think the spirit of the M in MACH is all about. MACH is about building modern applications that scale and microservices is not essential for that, however, modularity, loose-coupling and cohesion are.
Facebook famously runs as a monolith, eschewing the convention. And you can’t say Facebook isn’t a modern, high-scale, multi-tenanted application!
With one of the largest development teams in the world, Facebook uses modularity to ensure small blast radius of change and and feature flagging to ensure rapid releasing. Facebook made the decision to focus on customising the virtual machine within which their code runs, rather than splitting their code up into separate services.
I also believe the M in Mach is a nod towards containerisation (yes I’m aware the letters don’t match up!). Containerised workloads are a very good idea in the vast majority of cases. This means your software is highly portable, modular, immutable (so if it runs on your machine it will run on the server/cloud) and can be run in a variety of different ways, including as distributed microservices, locally and even within the same process chain on a VM.
Copying and pasting someone else’s architecture is not going to solve your organisation’s problems. You must find your own path. MACH, indeed, may be the right path for you.
A is for API-first
MACH is great if you’re building composable platforms.
APIs (application programming interfaces) are – usually – easy to integrate with and great for abstracting away complexity that the user doesn’t need to know about.
APIs are also useful for surfacing the same functionality through a variety of different front-ends, even those front-ends that the API publisher doesn’t even know about. A common use case is sharing functionality between mobile apps and websites.
As long as “the contract” is stable, i.e. consumers of the API can expect the API specification to not change or break – APIs simplify composition, whereby “applications” simply become groupings of modules, with each module’s features provided through an API.
I’ve worked on several products which have tiers of features, and each tier (e.g. bronze, silver and gold) and each tier just adds additional modules into the user’s menu.
Consider the picture below, behind those power sockets are miles of regulated electric cables, substations, power stations, monitoring and alerting systems, experts, thousands of years of training. But as a user of that functionality, all we have to do is plug in.
This is the user experience APIs offer.
C is for Cloud-Native
The cloud is the default choice for scaling web systems as it offers flexibility, elastic scale and cost optimisations that are impossible if you run your own data centres.
The most expensive server is the one that isn’t being usedGregor Hohpe
Cloud-native generally means using Platform-as-a-Service features of the cloud, rather than simply lifting and shifting a virtual machine into the cloud and still being responsible for zero-customer-value tasks like upgrading the operating system on that VM. A simple heuristic to know if you’re using cloud native platforms or not by looking to see if you’re paying for the running of an operating system. You may need to know there’s an operating system somewhere in the stack because Linux and Windows behave differently, but usually you’re cloud native if you don’t have to pay for that to run. You just pay for using the PaaS services that run on that abstracted-away OS.
When you only pay for the PaaS services you use, your costs become a proxy for customer engagement and usage.
IMPORTANT NOTE: Before embarking on a cloud migration, let your finance team know first!
Cloud economics mean a dramatic flip from a capital expenditure (CapEx) based IT budget to an operational expenditure (OpEx) model. This reduces cost predictability, but can reduce costs overall once the cloud environment is optimised.
Building applications in a cloud-native way helps focus teams on features and functionality and continuous delivery, while the cloud platform (via your SRE or Platform Team, the unsung heroes of your web-scale products) deals with scale, resilience and infrastructure.
H is for Headless
API-first and Headless go together. Headless platforms are those built without a specific front end in mind.
By hiding functionality behind an easy-to-integrate-with API, any front end that can consume an API can surface your functionality.
When I say “front end” I include anything that a user directly interacts with, not just mobile apps and websites but voice assistants and smart devices around your home or office too. Headless platforms fit nicely with Backends for Frontends (BFFs) which allows front end developers to create a specialised API for their front end to use, and this API calls down to the main platform.
Netflix uses the BFF approach to provide optimised experiences for streaming to TVs, the web player, Sony Playstations, etc.
MACH isn’t new. It’s really just a formalisation of good practices into a cohesive and high level mnemonic we can all substitute for a set of practices we’re all probably already doing.
If you’re building software delivered over the web (i.e. via HTTP and its related protocols) then it makes a lot of sense to host in the cloud for the flexibility, scalability and metered-billing reasons. This makes the cloud a great choice for start-ups that need to bootstrap their way to product-market-fit. For larger organisations, the cloud still makes sense as means you don’t have to try and right-size your infrastructure and can scale down your estate when it’s not in-use.
Building applications first as headless platforms simplifies delivery of user interfaces, but if the product is really successful it almost instantly gives you a Developer Platform allowing 3rd parties to build and maintain front ends. Through platform fees and pay-per-request billing options, your headless platform just went from being a cost centre to being a revenue stream. Developer platforms also mean your core functionality (hidden behind the APIs) can reach new users without you having to invest time and effort building those new front ends. Let your community do it!
And finally, just to return to the M. It is important not to enter into Microservices architectures lightly. Consider if each piece of your application really needs to scale at different orders of magnitude. Consider if you want your teams to release into isolated execution environments – and be sure about the reasons why. Consider how your train your teams to deal with the implications and failure modes of microservices, such as failure of distributed transactions, building sagas, dealing with master data, and transient network errors.
Always, ALWAYS (and saying “always” as an architect makes me cringe inside a little, but it’s true) build modular software. Even as a small team, separate your concerns at least. And if your software really does need independent releases and scalability, you want your teams to own the costs of their features, you have good monitoring and alerting, AND a team to own the infrastructure concerns of microservices, then go for it!