Bliki: MonolithFirst

As I hear stories about teams using a microservices architecture, I've
noticed a common pattern.




Almost all the successful microservice stories have started with a
monolith that got too big and was broken up

Almost all the cases where I've heard of a system that was built as a
microservice system from scratch, it has ended up in serious trouble.

This pattern has led many of my colleagues to argue that you
shouldn't start a new project with microservices, even if you're
sure your application will be big enough to make it worthwhile.
.


Microservices are a useful architecture, but even their advocates
say that using them incurs a significant
MicroservicePremium, which means they are only useful
with more complex systems. This premium, essentially the cost of
managing a suite of services, will slow down a team, favoring a
monolith for simpler applications. This leads to a powerful argument
for a monolith-first strategy, where you should build a new
application as a monolith initially, even if you think it's likely
that it will benefit from a microservices architecture later on.



The first reason for this is classic Yagni. When you begin a new
application, how sure are you that it will be useful to your users?
It may be hard to scale a poorly designed but successful software
system, but that's still a better place to be than its inverse. As
we're now recognizing, often the best way to find out if a software
idea is useful is to build a simplistic version of it and see how
well it works out. During this first phase you need to prioritize
speed (and thus cycle time for feedback), so the premium of
microservices is a drag you should do without.



The second issue with starting with microservices is that they
only work well if you come up with good, stable boundaries between
the services - which is essentially the task of drawing up the right
set of BoundedContexts. Any refactoring of functionality
between services is much harder than it is in a monolith. But even
experienced architects working in familiar domains have great
difficulty getting boundaries right at the beginning. By building a
monolith first, you can figure out what the right boundaries are,
before a microservices design brushes a layer of treacle over them.
It also gives you time to develop the
MicroservicePrerequisites you need for finer-grained
services.



I've heard different ways to execute a monolith-first strategy.
The logical way is to design a monolith carefully,
paying attention to modularity within the software, both at the API
boundaries and how the data is stored. Do this well, and it's a
relatively simple matter to make the shift to microservices. However
I'd feel much more comfortable with this approach if I'd heard a
decent number of stories where it worked out that way. [1]



A more common approach is to start with a monolith and gradually
peel off microservices at the edges. Such an approach can leave a
substantial monolith at the heart of the microservices
architecture, but with most new development occurring in the
microservices while the monolith is relatively quiescent.



Another common approach is to just replace the monolith entirely.
Few people look at this as an approach to be proud of, yet there are
advantages to building a monolith as a
SacrificialArchitecture. Don't be afraid of building a
monolith that you will discard, particularly if a monolith can get
you to market quickly.



Another route I've run into is to start with just a couple of
coarse-grained services, larger than those you expect to end up
with. Use these coarse-grained services to get used to working with
multiple services, while enjoying the fact that such coarse granularity
reduces the amount of inter-service refactoring you have to do. Then
as boundaries stabilize, break down into finer-grained services. [2]



While the bulk of my contacts lean toward the monolith-first
approach, it is by no means unanimous. The counter argument says
that starting with microservices allows you to get used to the
rhythm of developing in a microservice environment. It takes a lot,
perhaps too much, discipline to build a monolith in a sufficiently
modular way that it can be broken down into microservices easily. By
starting with microservices you get everyone used to developing in
separate small teams from the beginning, and having teams separated
by service boundaries makes it much easier to scale up the
development effort when you need to. This is especially
viable for system replacements where you have a better chance of
coming up with stable-enough boundaries early. Although the evidence
is sparse, I feel that you shouldn't start with microservices unless
you have reasonable experience of building a microservices system in
the team.



I don't feel I have enough anecdotes yet to get a firm handle on
how to decide whether to use a monolith-first strategy. These are
early days in microservices, and there are relatively few anecdotes
to learn from. So anybody's advice on these topics must be seen as
tentative, however confidently they argue.




Further Reading

Sam Newman describes a case study of a team considering using
microservices on a greenfield project.





Notes


1:
You cannot assume that you can take an arbitrary system and
break it into microservices. Most systems acquire too many
dependencies between their modules, and thus can't be sensibly
broken apart. I've heard of plenty of cases where an attempt to
decompose a monolith has quickly ended up in a mess. I've
also heard of a few cases where a gradual route to microservices has
been successful - but these cases required a relatively good
modular design to start with.





2:
I suppose that strictly you should call this a "duolith", but I
think the approach follows the essence of monolith-first
strategy: start with coarse-granularity to gain knowledge and split later.






Acknowledgements

I stole much of this thinking from my coleagues: James Lewis, Sam
Newman, Thiyagu Palanisamy, and Evan Bottcher. Stefan Tilkov's
comments on an earlier draft played a pivotal role in clarifying
my thoughts. Chad Currie created the lovely glyphy
dragons. Steven Lowe, Patrick Kua, Jean Robert D'amore, Chelsea
Komlo, Ashok Subramanian, Dan Siwiec, Prasanna Pendse, Kief
Morris, Chris Ford, and Florian Sellmayr discussed drafts on our
internal mailing list.


Share:

 •  0 comments  •  flag
Share on Twitter
Published on June 03, 2015 07:06
No comments have been added yet.


Martin Fowler's Blog

Martin Fowler
Martin Fowler isn't a Goodreads Author (yet), but they do have a blog, so here are some recent posts imported from their feed.
Follow Martin Fowler's blog with rss.