Microservices (and decentralised data management)


Copyright 2014-19 Graham Berrisford. One of more than 300 papers at http://avancier.website. Last updated 28/02/2019 12:43


This paper was first written in June 2014 with reference to what Martin Fowler (a brilliant writer) then said about microservices on his web site.

It was initially written to support the architect training courses advertised on our web site.

It has been extended to answer questions posted in Linkedin discussions and is now downloaded more than 10,000 times a year.

It draws from discussions with software architects about difficulties they are having with microservices.

And from discussions with EA teams about the need govern “agile” enterprise application development.


To quote from comments and discussion in Linkedin

·         “At last, a post on architecture with some real content.”

·         “This is worth reading again and again and sticking in the diary to read again.”

·         “Watching a presentation on Microservice Architecture I was astounded by the lack of perception [of the points in this paper].

·         “Your analysis of loose coupling is a poetry that everybody getting into system integration should read several times until it is really understood.”


Motivations and take aways. 2

What is a microservice?. 4

An aside on terminology torture. 4

Modular design (1970s) 5

Microservices architecture. 7

Microservices as server-side application components. 7

True (and other) microservices. 10

Issues raised by microservices. 13

CAP theorem, ACID and BASE.. 13

Lessons from CBD history. 16

Particular conclusions and remarks. 17

General conclusions and remarks. 17

Footnotes. 19


Motivations, tradeoffs and take aways

In essence, the idea behind microservices is that small systems are easier to build and maintain than large ones.

But people have associated that one simple idea with many and various other ideas.

An architect recently complained his CIO using the term as meaninglessly as the term “SOA” has been used for many years.


This paper was written to:

·         make sense of the term “microservice

·         steer people away from badly-designed, hard-to-maintain and poorly-performing microservices

·         encourage enterprise and solution architects to take responsibility for governing software architects.


There is much advice to be found on microservices; and some of it is good e.g. here.

But beware advice from technology vendors, and know that microservices are not a panacea, since all is tradeoffs.


What is the motivation?

The term micro implies subdividing something that could have been macro.

Of four motivations that have been advanced for microservices, the last two are interesting here.


-1- To maintain data stores that are already distributed and separately managed.

This is not interesting here, because it describes the application portfolio most enterprises already have.

And integrating discrete applications is a system integration task as it ever has been.


-2- To separate what must be coded using different technologies.

This is not interesting here, because such application components are naturally discrete.

And it seems advisable to not to mix technologies unless you have to.


-3- To enable very high throughput (by processing transactions in parallel components).

Exceptional requirements require exceptional designs, for which a price must be paid.

Few enterprise applications have a throughput high enough to require division to parallel microservices.

Solid state drives and in-memory data storage can handle remarkably high transaction volumes.


-4- To facilitate agile development.

This seems the most common motivation, and the one Fowler clearly had in mind.

The aim is to help a small team develop and deploy a microservice quickly.

Optimally, a small team can build and readily maintain it, with minimal disruption to what other teams are doing.


All is trade offs

Regarding the last motivation, it is important to recognise that agile principles can be in conflict.

The classic tradeoffs in agile development are these.


Agile principle

Contrary agile principle

Keep the system simple

Decouple (logically coupled) subsystems

You ain’t gonna need it

Design for future flexibility


Naturally (as Conway said) team structures tend to reflect architecture structures.

Where the reverse applies - architecture structures reflect team structures - a price may have to be paid.

For example, the price for decentralised data management may be much more complex messaging.

Where subsystems are logically coupled they are coupled, no social structure can change that, or remove inevitable complexities.


Take aways for those who don’t want to read the whole paper

Fowler's 2014 definition of microservices' nine characteristics (below) is reasonably well established.

Microservices are not new or sophisticated, merely a design pattern first promoted in the 1990s. 

I have seen the pattern used well, and used very badly; all is trade offs.


In the babble that software architecture discussion has become, the term is widely abused.

To use the term for every module behind an API is to make them term meaningless and valueless.

A small application is just a small application – nothing new or special about that.

A silo application is just a silo application – nothing new or special about that.

Small and silo applications are readily developed using agile principles – because they are naturally easier to write and to change.

And there is nothing new of special about wrapping up a small or silo application behind an API.


The term micro implies subdividing something that could have been macro.

But again, the classic tradeoffs apply, and excessive modularisation leads to excessive messaging.








Macro subsystems





Micro subsystems






Often, a microservices architecture involves dividing what could be one coherent data store.

But dividing a coherent database schema into smaller (still related) schemas doesn’t reduce coupling,

It merely moves it from the database to the messaging system, at some cost to performance if not also integrity and availability. 


Smaller/simpler modules means larger/more complex messaging.

Separating modules leads to slower processing and disintegrity.

And therefore to the extra complexity of compensating transactions to restore data integrity.

(CAP theorem ignores this simple/complex trade off.)


OK, scalability is sometimes an issue.

But an ordinary RDMS can handle 20,000 transactions per second.


OK, message brokers and workflow engines can be useful.

But business rules are not best placed in the middleware.

Rules engines are niche tools; some rules are best at the user interface; some are best as near to the stored data as possible.

Some rules are best configurable, but you don’t want mission-critical business rules in the hands of users.


OK, domain-oriented modularity has its place.

But some gurus have encouraged the writing of over complex OO code on app servers.

Transaction scripts and subroutines thereof can be fine; and some code is better on data servers.


In short, there is no silver bullet, you can’t have everything.

What is a microservice?

One writer says a microservice is "a self-contained and independent unit with a well-defined scope and responsibility".

But this definition can fit everything from a single Java class to an entire CRM system.

Moreover, you could define a good API the same way.

And the notion that microservices are independent of each other is misleading.


One writer says "An API needs a house to live in and that house is a Microservice."

If everything that realises an API is called a microservice, then the term adds no meaning.

Every microservice is an application component, but not every component is a microservice.

Every microservice should have an API, but not every API encapsulates a microservice.


Martin Fowler's 2014 list of microservices' nine characteristics is included later.

Briefly, a true microservice is much as Fowler defined:

·         a micro application, encapsulated behind an API

·         a discretely deployable subdivision of what could be a monolithic application (a macroservice?)

·         it encapsulates one partition of what could be a monolithic data structure, and so “decentralises data management”.


Some say microservices are “gatekeepers” to data, but usually for update only, meaning the data can be accessed by others for analysis and reporting.

Some say microservices should be “isolated” and “autonomous” – but this ranges from questionable to impossible where data integrity is needed.

Some say dividing a monolithic application into microservices should not affect the services offered to clients - but it might if microservices are decoupled too far.

Some apply the term “microservice” things that are not true microservices – this might be OK (see below) but should be done knowingly.

An aside on terminology torture

Some use the terms system, component, process and service interchangeably.

Some use them with different (and sometimes contradictory) meanings.



In some standards from The Open Group

In Fowler’s writings for programmers


A structural building block that offers

multiple services (a service portfolio) to its clients

A software unit (component) that is

independently replaceable and upgradeable.


A behavior composed of steps

in a sequence that leads to a result.

An instance of a component executed on a computer.

It contains executable code and current state data.

(Some OS allow it to contain multiple concurrent threads of execution.)


The external or  declarative  view of behaviour that

encapsulates one or more processes.

An out-of-process component,

typically reached by a web service request or RPC.


Remember Martin Fowler’s process and service correspond to application components in TOGAF and ArchiMate.

And TOGAF’s Function is a logical component that groups behaviors by some cohesion criterion other than in sequence (which is a process).


It is commonly said that “enterprise architecture views the enterprise as a system, or system of systems”.

But there are profound misunderstandings of what this means.

To call every problem, situation or business “a system” is unhelpful.

It is important to distinguish:

·         a social network in which people communicate

·         a social system in which people realise role and rules.


An enterprise is one social network that realises many social and technological systems.

Those systems may overlap, duplicate or even be in conflict.

Enterprise architecture is about applying change control to large-scale, generational, system change.


In short, beware the terminology clashes that are the curse of every writer in this field.

In EA terms, a microservices architecture would be better called a microcomponent architecture.

The services offered by the wider monolithic application should remain unaffected by division into microservices, but they might be affected.

Modular design (1970s)

Enterprise application design is often discussed in terms of technologies.

But abstract away from the technologies and you see a story of modular design.

In the 1960s, Larry Constantine promoted strong cohesion within a module and low coupling between modules.

By the 1970s, several modular design principles were widely recognised.


Design principles

Meaning that


Components encapsulate cohesive data structures and algorithms

Loose coupling

Components are encapsulated by and communicate via interfaces


Components can be invoked and orchestrated by higher processes


Components are designed for use by different clients


Components are maintained in several versions to enable incremental change


Trade offs

It is important to recognise design principles above are not mandatory goals, only means to some ends.

Ever since the 1970s software designers have debated now best to scope a module, separate modules and integrate modules.

Always, one has to consider what trade offs have to be made between requirements.

For example, there are trade offs between flexibility and simplicity, scalability and integrity.


Of course, it is quicker to design and build a small subsystem than a large system.

But the smaller and simpler each sub system, the less useful it is, and the more complex the integration between subsystems.

This table lists my universal modularisation trade offs.


Agile developers’ dream

Enterprise architects’ nightmare

Smaller, simpler modules

Larger, more complex module dependency & integration

Module isolation/autonomy

Duplication between modules and/or difficulties integrating them

Data store isolation

Data disintegrity and difficulties analysing/reporting data


Relevance to enterprise architecture?

EA was a response to silo system proliferation.

Themes in EA literature include data and process quality, data and process sharing, data and process integration.


Loose-coupling is often promoted as though it is always a good thing, but this is not true.

Designing systems or components to be “isolated” and/or “autonomous” can lead to data and processes disintegration.

EAs ought to be wary of excessive decoupling of software components across a network and/or via middleware.

Since it can create needless disintegrities and complexities, not to mention needless costs and performance issues.

Above all, EAs need to be aware that excessive decoupling can hinder how customers or employees perform business processes.


Application integration fashions

There have been many technologies and design fashions in the last fifty years.

Read SOA and the Bezos mandate for a notes on:

·         RPC: Distributed programming

·         DO: Distributed Objects

·         CBD: Component-Based Design

·         SOA: Service-Oriented Architecture

·         REST: Representational State Transfer

·         SOAP versus REST

·         The Bezos mandate

Microservices architecture

A microservices architecture divides an application into modules or components - confusingly called micro services.

It might be seen as an application of modular design, OO design, CBD or SOA principles.

Microservices might be distributed and integrated over a network, but this is not essential.


Martin Fowler (2014) defined microservices in terms of nine characteristics, most of which amount to principles.

The first six about are how best to scope a module, separate modules and integrate modules.

·         Componentization (discussed in this paper)

·         Decentralized data management (discussed in this paper)

·         Decentralized governance (click on the link to read more)

·         Organisation around “Business Capabilities” (click on the link to read more)

·         Smart endpoints and dumb pipes (click on the link to read more)

·         Design for failure and "You build, you run it" (click on the link to read more)


Fowler’s last three principles are drawn from the wider agile development movement, not discussed here.

·         Products not Projects

·         Infrastructure Automation

·         Evolutionary Design

Microservices as server-side application components

c1980, an EA vision was a central database, supporting one application that served all the enterprise’s business functions.

That vision became unachievable as enterprises deployed ever more applications, which were increasingly distributed.

The vision evolved: EA divided the enterprise into “segments”; and the centralised data vision was recast as “single-version-of –the-truth”.

EA now involves “master data management” within each segment of the enterprise, and sometimes across segments.

EA expects each enterprise segment to be supported and enabled by many applications; some in-prem and some in-cloud.


Much as an enterprise may be divided into segments, an enterprise application may be divided into application components.

A typical client-server enterprise application processes successive transactions and is divided into three layers.

Microservices divide the server-side of what could be one large application into components that are supposedly autonomous.

By “decentralising data management” Fowler implies dividing what could be one persistent data structure into parts.

The idea is that each microservice encapsulates the data it needs; it does not directly access the data maintained by any other microservice.

Each is an application component that can perform one or many transactions or partial transactions.


Size matters!

You might see microservices as a scaling down of the “Bezos mandate” and/or Service-Oriented Architecture.

In other words, as extending the principle that components are distributed across a network and communicate via APIs.

However, microservices do not have to be distributed across a network.

Other modularisation strategies are no less service-oriented; and SOA does not say how to divide an application into modules.


You might better view microservices as a scaling up of OO design principles.

In other words, as a response to complaints that the granularity of “objects” is too small for architecture-level design.


Hierarchically layered client-server architecture

An enterprise application enables or supports one or more business roles and processes.

It encapsulates some business rules, business knowledge or business capability.

A few enterprise applications are purely algorithmic, or need very little stored data.

But the majority maintain, or at least need access to, a substantial business data store.


Fowler says an enterprise application is typically composed of three horizontal layers, as shown below.


Client-side user interface

Typically HTML pages and javascript running in a browser on the user's machine

Server-side application

Controllers: handle requests/commands from the client

Views: populate views/pages sent to the client.

Models: retrieve and update data, applying business rules

Data store

A persistent data structure maintained using a database management system.

Typically a relational DBMS, but there are many data store varieties.


Dividing an application into three layers dates back to the 1970s - the days of COBOL and pre-relational databases.

The layers form a client-server hierarchy, meaning each layer requests services from the layer below

Despite the OOPers mantra that business rules belong in the middle later, many regard the data layer as the best place for data-centric business rules.

Middleware may be used to connect layers, but Fowler says "smart end points, dumb pipes", meaning don't put business rules in middleware.


Dividing the server-side application

Fowler says the server-side application is typically a single executable.

One large application serves many requests/commands from clients.

Moreover, it is seen as a single software development unit.

So changes to requests/commands involve building and deploying a new version of the whole server-side application.


Microservices are subdivisions of the server-side application layer.

Each microservice receives a subset of the service requests that clients make of the whole application.

The ideal is that each of these application components can be built and tested in parallel.


Client-side user interface

Screens / Pages

Server-side application

Customers, Agents, Sales

Reservations, Rooms, Hotels


How to divide one application into microservices? Fowler suggests:

·         “Organisation around Business Capabilities” according to Domain-Driven Design (see footnote 1).

·          “Decentralized data management”, which is discussed in this paper.


“At a first approximation, we can observe that microservices map to runtime processes, but that is only a first approximation.” Fowler


Client components (of any kind) do not have to be invoked a microservice via a message broker.

Microservices can be invoked using web service requests, the OData protocol, or whatever suits.

The closer microservices are adjoined in location and time, the more likely synchronous request-reply invocation will be appropriate.


Dividing the data store

Microservices imply not only dividing the application layer processing of what could be one cohesive data structure.

But also partitioning that data structure to match the division of the application layer into microservices.


“A microservice may consist of multiple processes that will always be developed and deployed together, such as an application process and a database.” Fowler

In other words, an application layer microservice cannot work without its data store.


To keep thing simple, let us minimise the need for a data abstraction layer between application and data layers.

In other words, the class diagram of the application layer and the data model of the data layer are variants of one logical domain model, and divided the same way.


Client-side user interface

Screens / Pages

Server-side application

Customers, Agents, Sales

Reservations, Rooms, Hotels

Data store

Customers, Agents, Sales

Reservations, Rooms, Hotels


If you decouple the microservices’ data structures, and store them separately, then you need a cross-reference between them.

At least one entity type is duplicated in adjacent microservices' data stores, with a common primary key, but different, attributes and relationships.

That is an old and generally applicable idea; it can be applied however you choose to divide work between horizontal layers.


On division of work between horizontal layers

Regardless of division into vertical partitions, an idea that Fowler seems to presume is that all business logic is in the application layer.

However, a data model captures business-specific terms, concepts, data types, data derivation and data integrity rules.

And coding data-centric rules next to the data is a rational design strategy.

So it is common to find data-centric business rules in the data layer.

Especially basic consistency/integrity rules such as: “no row can be inserted into the Sale table unless there is a corresponding row in the Customer table”.

And perhaps: no row can be removed from the Customer table if that Customer has Sales with future-dated Reservations.

True (and other) microservices

Macro applications might be seen as the enemy here, but a macro application is always modularised one way or another.

As Fowler says, most business applications handle a series of discrete business transactions (event-triggered processes).

And they maintain a cohesive data resource – describable as data entities related to each other in a network structure.


This table maps business event-triggered business processes against business data entities accessed.




Sale item

Product type


Register customer




Place order





Complete sale





Launch product




Recall product





Event-oriented modularisation

You can modularise an application into one module for each event-triggered process to be completed.

That was the expectation in using structured analysis and design methods in the 1980s

Duplication is removed by factoring out common sub-routines (done well, this gives the leanest design).


Procedural microservice (handles 1 whole transaction, has access to the whole data structure)

This is not a microservice of the kind Fowler discussed.

You can partition the application into one module for each command/transaction script.

A transaction is a process that has an access path through the persistent data structure.

You can both design and deploy each transaction script separately.

So, each is performed by a component that has complete responsibility for it.


Some transactions will contain duplicate parts - same access path and same code.

You can and should factor out any substantial common part into a reusable module.

(Aside: reuse can be classified as a) direct b) copy and paste c) copy, tailor and paste.)

Two or more transaction scripts may directly reuse modules that they share.

You can analyse transactions scripts looking for common processing, and “factor out” shared modules.

And/or design modules from the bottom up to encapsulate entities or aggregate entities in the persistent data structure.

You’ll probably need a simple hierarchical module dependency diagram to track inter-dependencies.)

Entity-oriented modularisation

You can modularise an application into one module for each data entity (cf. “object-based” design in the 1980s).

The entity modules are coordinated to complete event-triggered processes by

·         Choreography: one entity module calls another, and so on, as need be or

·         Orchestration: an event-triggered process invokes entity modules

·         A mix of both the above (using the GRASP pattern).


Modules that encapsulate more-or-less normalised entities are too small to be deployed separately as microservices.

Cf. Fowler’s first rule of distributed objects: “Don’t distribute your objects!”

Objects are too small, and coordinating them in higher level processes is horrendously inefficient.


However, Fowler proposes the design of microservices should decentralise data management and governance.

Which implies a microservice encapsulates a data structure considerably larger than a normalised data entity.

If you are thinking of “aggregate entities” as in Evans’ Domain-Driven Design, then see footnote 1.

Another approach is to apply cluster analysis (the north-west corner method) to the table above to aggregate data entities acted on by the same events.

Either way, you can identify a cohesive data structure that is more substantial than a normalised data entity.

And then design an application component that will apply several transactions to several data entities.


Pseudo microservice (handles a cluster of whole transactions, has access to the whole data structure)

This resembles a true microservice in scope, but does not completely encapsulate the data.

A pseudo microservice is a bundle of transaction scripts that are managed as a discrete application layer component.

It processes all transactions that are clustered using some cohesion criteria.

E.g. cluster all transactions that start at the same data entity (or in the same aggregate entity).


Pseudo microservices are separately deployable application layer components.

They can be assigned to different individuals or teams for development and testing.

Thus, they can suit agile development, accepting that data management remains centralised.


Design options include: allow pseudo microservices to compete for the same data (limits scalability).

Duplicate data needed by several microservices (increases disintegrity and complexity).


True microservice (handles a cluster of whole and partial transactions, has access to one part of the whole data structure)

A true microservice encapsulates a discrete group of data entities - an aggregate entity or more.

Ideally, the data structure is sufficiently wide that a microservice can complete many (most?) service requests on its own.


There are recognised techniques for dividing an OOP domain model and dividing a data model.


Logical structure

Divisible into

App server

OOP domain model

Aggregate entities (see footnote 1)

Data abstraction


Data server

Data model

Hierarchical structures (linked by many-to-many link entities)


Ideally, the data server and app server layers of the application are partitioned in the same way.

Otherwise, the data abstraction layer between them will be complex, and undermine the hoped-for benefits of microservices.


What if one business transaction needs to access the data encapsulated by more than one microservice?

The business transaction can be completed by coordinating microservices by:

·         Orchestration: an overarching workflow process invokes partial transactions in several microservices .

·         Choreography: one microservice calls another, and so on, as need be.

·         A mix of both the above (using the GRASP pattern).


Or else, if you choose to deploy each microservice with all the data it needs, you have to duplicate some data between data stores.

This leads to the complexity of additional processes to align data stores after a transaction – asynchronously - as best they can.



A naive microservice will tend to cache more data than it needs for some or most of the transactions it processes.

The code on the app server tier might be structured into model, view and controller objects in an MVC pattern.

The many possible ways to map transactions and microservices to the elements of an MVC pattern are not explored here.

Issues raised by microservices

Decoupling is an important tool of design; but it means many things, and can be overdone.

There are many ways to decouple application components: physical decoupling using network and/or messaging technologies is not logical decoupling.

There are many ways to integrate application components: exposing APIs over an IP network is only one way.

Read SOA and the Bezos mandate for discussion of component granularity, network use and middleware use.


For some, loose-coupling via messaging has become a mantra, but there are always trade offs, as this table shows.


Couple via synchronous request/reply for

Decouple via asynchronous messages/events for




Scale (very high volume and/or throughput)

Adaptability/Manageability (of smaller distributed components)

Availability (of smaller units of work) and Partition Tolerance


Things to think about include:

·         Physical decoupling makes logical coupling more complex.

·         Naïve architecture guidance - can mandate decoupling, asynchronicity and scalability where not needed

·         Response time – where one transaction requires microservices that communicate via network and/or messaging.

·         Availability – where synchronous access is needed to partitioned/distributed data stores.

·         Scope/complexity creep – where microservices are increasingly hooked together.

·         Business data and process integrity – where BASE replaces ACID.

·         Application maintenance – where multiple design patterns and technologies are used.

·         Best practice use of CQRS/Event Sourcing.

CAP theorem, ACID and BASE

We are talking about the server-side of an enterprise application.
A remote client sends a service request to a point of entry on the server-side.
That service request is a business transaction, a command or query, definable in a declarative service contract.
The service contract defines I/O data with reference to one or more persistent data entities.


Suppose we have modularised a macro application into several true (entity-oriented) microservices.

Ideally, most business transactions don’t stray beyond one microservice.

But what about those business transactions that do involve two or more distributed microservices?


CAP theorem

The famous CAP theorem says you can’t have all three of Consistency (integrity), Availability and Partition (broken connection) tolerance.

It doesn’t mention a fourth thing you want from a design – Simplicity.

The disintegrity that results from dividing a cohesive data model tends to increase the complexity of a system.

Allowing data to become inconsistent, then restoring integrity by compensating transactions, is more complex both for programmers and for a business.


ACID versus BASE

This table contrasts two ways to implement a business transaction.


ACID when you

BASE when you

Want every business transaction to succeed

Want to simplify design and development

Want consistent data

Want to get a business transaction started, even if it fails later

Don’t mind the complexity of compensating transactions

Can live with some inconsistency for a while (perhaps forever)


ACID transactions for consistency/integrity

Often, data integrity is important to business operations

A client wants a business transaction to succeed or fail completely before the server-side application replies.

A customer does not want to reserve a hotel room (using the sales agent microservice) that later turns out not be available (in the hotel administration microservice).


ACID means a transaction is atomic, consistent, isolated and durable.

Here, it means microservices are coordinated synchronously on the server-side.
So, clients’ service requests are not affected by how the server-side modularised.


Aside: For scalability, microservices can be replicated on parallel server-side nodes.

Sticky sessions or state replication enable a load balancer to choose which node responds.


To keep things simple, it is best if all the required data can be stored in one place.

Then, the database management system can be used to roll back a transaction when a business rule is violated.

It can also save some programming effort by maintaining referential integrity.

And support analysis of data for management information purposes.

If data is distributed, it may be necessary to hand-code the two-phase commit units a transaction manager could handle.


BASE for very high throughput by partitioning

Naturally, it is easier and quicker to develop a module that has minimal interaction with others.

For agility, developers want their microservice to work on its own, and reply to a client immediately with minimal dependency microservices.

For scalability, they want to isolate modules physically as well, deploying them on differ server-side nodes.


BASE means an application is basically available, scalable and eventually consistent.

Here, it means that one microservice may reply to a client before that client’s desired business transaction is completed.

Other microservices are coordinated later, asynchronously, and compensating transactions are performed if need be.

The result is that clients become aware of, and are affected by, modularisation into microservices.


Basically available

The idea is that a microservice can serve its clients well enough without immediate reference to other microservices.

A microservice can complete some business transactions immediately, and set other business transactions in motion.

The presumption is that a client will be happy to see a business transaction started, with no promise it will be completed.

E.g. a customer reserves a hotel room using the sales microservice, without the promise that the room will be available.



Today, an ordinary relational database can handle many thousands of transactions per second.

Very high transaction volumes can be handled by beefing up the data server and using solid state drives.

To handle extraordinary transaction volumes, the data store can be partitioned in one of two ways.

·         Sharding: this means partitioning the data store into separate data populations (perhaps by geography or region?).

·         Functional scaling: this means partitioning the data structure by subject matter (e.g. customers and products).


Microservices can enable functional scaling, but this is not a general motivation.

FAANG is an acronym for five large IT-centric businesses, namely Facebook, Apple, Amazon, Netflix and Alphabet’s Google.

To which you might add eBay and Spotify.

Hard cases make bad law is legal maxim.

In other words, a general law is better drafted for average or common circumstances.

Not many businesses are like the seven mentioned above.

Whatever those internet giants do to handle extreme business transactions volumes is not necessarily optimal for your business.


Eventual consistency

Doing business using inconsistent data is a business issue before it is a technical issue.

Any business transaction that spans two or more partitions needs special attention.

The BASE strategy is to divide a business transaction into smaller transactions, each performed by a different microservice.

And to allow cases were a whole business transaction cannot be completed in one go.

You must analyse possibility that data becomes inconsistent, the impact that has on business operations, and when and how to restore data integrity.

E.g. what to do if a customer reserves hotel room (using the sales agent microservice) that turns out not be available (in the hotel administration microservice)?

You have to analyse and design additional compensating transactions to correct or undo the unwanted effects of business transactions that start, but cannot be completed.

Lessons from CBD history

Microservices can be seen as a renewal of the Component-Based Design fashion in the 1990s.

CBD partitioned a cohesive data model into chunks, each an aggregate entity maintained by a “business component”.


How did developers maintain data integrity?

Some worked to the presumption that few transactions stray beyond the bounds of an aggregate entity.

Some (as in domain-driven design) gave the root entity in each aggregate responsibility for transaction management.

I suspect these developers may have ignored some data integrity tests that could be made.

Still, what to do about those business transactions that do require access to data in more than one aggregate / business component?


Maintaining all the aggregate entities in one single data store

This facilitates queries, data analysis and reports.

The optional update patterns are

·         Synchronous ACID transactions maintain data integrity: Complete a two phase commit unit, integrate components via RPC or middleware; OR use the DBMS transaction management to maintain cross-component data integrity.

·         Asynchronous BASE pattern, allow data integrity temporarily: Reply before completing the transaction, then integrate components via using RPC or middleware to complete it, performing compensating transactions as need be.


Maintaining the aggregate entities in distinct data stores

This hinders queries, data analysis and reports.

The optional update patterns are:

·         Synchronous ACID transaction patterns maintain data integrity: Complete a two phase commit unit, integrate components via RPC or middleware; OR use a distributed/federated transaction manager.

·         Asynchronous BASE pattern, allow data integrity temporarily: Reply before completing the transaction, then integrate components via RPC or middleware to complete it, performing compensating transactions as need be.


Some options couple components more obviously that others; but all options couple components in some way.

Particular conclusions and remarks

Publishing "decoupling" as a general principle can accidentally encourage excessive decoupling of software components across a network and/or via middleware.

EAs ought be concerned about creating needless disintegrities and complexities, not to mention needless costs and performance issues.

The issues, principles and tradeoffs are largely vendor and technology neutral.

If EAs can't directly govern Technical and Software Architects, then they need to be socialised with Solution Architects who can do this on their behalf.


Assisting agile development is a plus for any modular design strategy.

A clean division into business components/microservices can suit the division of work between small teams.

However, remember Berrisford’s universal trade offs.


Agile developers’ dream

Enterprise architects’ nightmare

Smaller, simpler modules

Larger, more complex module dependency & integration

Module isolation/autonomy

Duplication between modules and/or difficulties integrating them

Data store isolation

Data disintegrity and difficulties analysing/reporting data


Be cautious about partitioning what could be one cohesive data structure.

Beware naïve principles, look at realistic requirements and assess trade offs.

·         Flexibility? Beware this usually requires a more complex design.

·         Scalability? Be realistic about the need, and assess the cost of allowing and restoring integrity.

·         Decoupling? Beware that decoupling related components physically does not decouple them logically.

·         Reuse? Beware that dividing an application does not usually create components readily reusable in other contexts.

·         Keep it simple? Beware BASE can be considerably more complex than ACID.

·         Agile development? Grouping transaction scripts into “pseudo microservices” is a rational way to divide work between individuals or teams.

General conclusions and remarks

In short, there is no silver bullet, you can’t have everything, there are always trade offs.

Read SOA as per the Bezos mandate for some SOA history.

Read Domain-Driven Design, Transaction Script and Smart UI for discussion of the simple v complex trade off.

Read Smart endpoints and dumb pipes for discussion of the synchronous v asynchronous trade off.


Programmers are intelligent people, and know useful stuff.

Having a programming background helps people become good architects.

It gives them insights that are valuable at the architecture level.


Nevertheless, there are difficulties out there.

·         Technology vendors encourage programmers to use technologies they don’t need.

·         Industry analysts repeat what technology vendors tell them.

·         Reading software guru books can encourage programmers to use patterns designed for problems they don’t have.

·         Some programmers are under-educated in the very wide variety of ways to code software – and trade offs between them.

·         Some programmers like extend their CV with the latest buzz words.


Advances in hardware can always be negated by questionable software engineering practices.

The ability of software to consume ever more electricity is endless given presumptions such as:

·         Following latest design fashion without question.

·         Copying what Google or Amazon do.

·         All components should be loosely coupled.

·         All inter-component messages must be sent via middleware.

·         All components should be open to extension but closed to amendment.

·         Integrity is best achieved by eventual consistency.

·         New data store types are better than relational databases.

·         Complex data abstraction layers are needed.

·         Microservices are the answer.


The result is that programmers can easily generate solutions that are more complex than is justifiable.

Complexity can appear in excess code, data abstraction layers, message passing, compensating transactions and middleware dependency.


Vendors, industry analysts and commentators encourage programmers to decouple application components.

Concerns about this include:

·         there are a dozen ways to be coupled or decoupled, so the meaning of the direction is unclear.

·         physical decoupling is not logical decoupling.

·         decoupling tends to increase complexity, slow down and disintegrate business processes.

·         the optimal degree of coupling varies with the granularity and cohesiveness of the specific components at hand.

·         following the direction has led to overuse of middleware and consumes excessive server-side resources.


As Craig Larman wrote: the problem is not high coupling per se, it is high coupling between components that are unstable in some way.

Rather than directing decoupling throughout, architects should be balancing trade offs and providing more nuanced guidance.


How to save the enterprise from the cost, risks and issues of following software design fashions?

EA needs solution architects to shape and steer programming efforts in an EA-friendly direction.

They have a role to play in abstracting and repeating lessons learned from experience.


Don’t be over eager to use the latest design pattern/method or technology.

Beware that ungoverned agile development can lead to duplication, disintegrity and complexity.

Keeping things simple, minimising unnecessary code and use of middleware, is a reasonable principle.

This can sometimes mean constraining programmers’ enthusiasm for “new” ways of doing things.


As the first slide in our enterprise and solution architect training says.

Think about the business context.

Don't forget the numbers.

There are many ways to design and build something.

You have to balance trade offs:

·         between qualities (e.g. flexibility or simplicity)

·         between what is best for the local system and what is best for a global system.

You are responsible for:

·         knowing there are many possible answers

·         ensuring trade offs are addressed and

·         recommending one or more options.



Design practices some relate to true microservices

Read Dividing an application into microservices and Domain Driven Design, Transaction Script and Smart UI for practices related to microservices.

Domain-Driven Design, CQRS and Event Sourcing are sometimes related to each other.

But Transaction Scripts can equally well publish Events (for others to consume) and log Events (for subsequent query and replay).

And you don’t need Domain-Driven Design or CQRS to design microservices, separate database update transactions from queries, publish Events, or use Event Sourcing.


Design by Contract (DBC) means a server will fall over if a client (any client) does not guarantee its preconditions.

Defensive Design means a server tests (or likely retests) its preconditions are met, and responds gracefully if not.

Distribution of microservices (or any software) between nodes tends to increases the need for Defensive Design.


You might see microservices as a scaling down of the “Bezos mandate” and/or Service-Oriented Architecture.

In other words, as extending the principle that components are distributed across a network and communicate via APIs.

However, microservices do not have to be distributed across a network.

Other modularisation strategies are no less service-oriented; and SOA does not say how to divide an application into modules.


(For more on this read SOA and the Bezos mandate).

Linkedin comments and discussion


Marc Bastien wrote

At last, a post on architecture with some real content.

Thanks Graham for elevating a bit the level of discussion about IT architecture above vendor sales pitches.

And for those that have a hard time understanding your post, that are lost in the terms, and find this subject too "esoteric", here's a friendly suggestion:

Don't rely too much on programmers that are good at doing the "real" thing.

Because most of them just don't have a clue about the impacts of what they are doing besides and above the code they deploy.

Not because they're​ not bright enough, but simply because they're busy doing their things.


Martin Cotter wrote:

This is worth reading again and again and sticking in the diary to read again.
The comment by Marc about coders who are brilliant but busy rings especially true.


Rob Dean wrote:

Watching a presentation on Microservice Architecture I was astounded by the lack of perception [of the points in this paper].

You cannot provide every quality attribute in any architecture.

Trade offs are the nature of engineering, regardless of the discipline.

Each service will contain some redundant code to enable it's isolation from the other services to allow for the horizontal scaling.

While removing one type of dependency you introduce others, such as state.

The only way to introduce reuse in these services is composing them from a configuration definition.

Also, while attempting to scale small units of functionality you introduce dependency scaling.

If you decouple Orders from Inventory as in the example, you will always need enough inventory services to support the orders.

The dependency remains intact even though the monolith gone.


Edin Nuhic wrote:

Graham, your writing on the subject is highly relevant.

TOGAF can often confuse people who misunderstand it.

However, you seem to be the one who analyzes things deeply and then tries to summarize what it all comes down to.

Your analysis of loose coupling is a poetry that everybody getting into system integration should read several times until it is really understood.

As you point out - there are two definitions of microservices

·         the one from Martin Fowler that addresses the organisational and the deployment aspects in the first hand

·         the other that addresses the performance.


This second advocates asynchronicity as a means of preventing idle slots waiting for a synchronous service to return.

[This bring something new to the table] and deserves a separate discussion.

It is strange that very serious people can mean so different things and call them the same name.

A few readers’ questions


-1- What makes a service a micro?

It is micro compared with the macro application it is a component of.


-2- What is micro about “pseudo-microservices”?

They are similar in size to true microservices.

Both process a subset of service/transaction requests from the client layer.

But pseudo microservices don’t wholly encapsulate the data they access.


-3- How does a microservice differ from a usual SOA style service?

What is a usual SOA style service?


-4- How important is independence of deployment - the devops aspect?

That suggests a distinct application, not a subdivision of one.

Unless it means deliberately dismembering a business process.


-5- How important are performance gains through asynchronicity and granularity.

Speed – could make things worse.

Throughput – important in some (probably rare) cases

Availability – it depends what the business wants to be available.


All free-to-read materials at http://avancier.website are paid for out of income from Avancier’s training courses and methods licences.

If you find the web site helpful, please spread the word and link to avancier.website in whichever social media you use.