
Well-Architected Monoliths Are Okay - kiyanwang
https://robertnorthard.com/devops-days-well-architected-monoliths-are-okay/
======
rossdavidh
A recurring pattern that I have noticed: 1) a company the size of Amazon,
Facebook, or Google runs into a problem that comes from their gigantic scale,
or the fact that they're trying to do something very different (e.g. Google
Maps compared to old-style web pages) 2) Big Company comes up with a new
technology to solve their problem 3) Many, many small companies that will
never become big enough to need this, and are doing far less exotic things
that require it, will try to make their ordinary web page into a microservice
single page app with a NoSQL backend, because that's what successful companies
do.

Imitating success often makes sense; after all, we don't want to imitate
failure. But your company is almost certainly not facing issues at all like
Amazon, Facebook, or Google, and also does not have nearly as many programmers
to do it.

~~~
latch
I call this: Headline Driven Development

Another good example are monorepos. A decision maker sees a headline about
Google and Facebook using monorepos and mandates his company to switch.
Unfortunately, he or she didn't read or didn't understand the actual article
that explains that it only works because of strict code reviews and extensive
integration tests.

~~~
xab9
We call it Hype Driven Development which is just as bad as Marketing Driven
Development... and yes, monorepos, don't even mention it, good heavens.

Another hype that keeps coming back is the magic of trunk based development
(with a random po reading some flashy article about feature switches as the
wonderous solution for a-b testing AND faster development).

Nowdays I even consider putting react and angular into this pack, since, you
know, "if it's good enough for facebook/google then it must be really good" \-
anyone ever tried to increase performance for a react site (and realizing that
precompiling templates was not exactly a bad idea years ago) or hitting the
wall with inline async helpers and rx magic might know my voes. But then
again, give me a fast and reliable server rendered site over an unsteable
trainwreck spa anytime and I will be happy.

~~~
blotter_paper
>anyone ever tried to increase performance for a react site (and realizing
that precompiling templates was not exactly a bad idea years ago)

I'm not sure I'm parsing this sentence correctly. Are you saying that
precompiling templates and rehydrating them doesn't cut it anymore? If so, why
not? I haven't used React much, but I've done some work in a framework with
similar principles and I felt like proper precompiling, with basic HTML
fallbacks cooked in where possible, provided all the performance of server
rendered sites with the added bells and whistles of SPAs (including that most
subsequent requests can load quicker than a full rerender, provided JS is
present).

~~~
xab9
Afaik the render part is purely dynamic and the advocated style of creating
closures with fat arrows to avoid scope binding (which is essentially the same
if done in the render section) is quite expensive in terms of performance.

React and fiber tries to be smart about rendering with tree section diffing,
but unless you use immutable, it's "not enough" to rely on - without immutable
even in a smaller redux app there is a good chance that you have unintentional
rerenderings triggered, which while may not create new tree branch renderings,
still need to be evaluated.

This of course applies to the client, I don't have experience with nextjs or
similar tools.

~~~
TomMarius
The issue with closures is easily solved, just declare it as class property
(or a const variable outside the component if you're using SFC) and then use
it instead of declaring it inside your render JSX. Any React-aware linter
would not let you declare closures in JSX.

~~~
xab9
Can you recommend a tsx-friendly linter and its setting? The sites I worked
with never followed this rule and whenever I tried to bring it up, it was too
late to refactor things (at least from a roadmap/burndown po/sm perspective)

~~~
TomMarius
I use tslint and tslint-react, the rule is named "jsx-no-lambda"

------
alexandercrohde
Understatement of the month. Last I heard, the HN consensus was that it's
better to delay microservices (personally I'd say wait until profitable or
>100 engineers).

Even Twitter, probably the most successful performant microservice-at-scale
company advocates waiting as long as absolutely possible to make
microservices. They said "It fixes one problem, and makes every other piece of
application development significantly harder."

~~~
oppositelock
The need for microservices has little to do with company size, they have to be
the right tool for the job. People mistakenly use them for scalability, or to
partition work between teams.

I'm in a small engineering org, and I split out a bunch of security critical
code from an unsecure monolith and moved that into a microservice, running in
a very tightly controlled and audited environment. A tiny part of my runtime
needed different security from the rest of it, and a microservice was the
easiest way to accomplish it. Now, I've traded a security problem for a
latency problem, as everything that used to be handled internally is now an
RPC - though this is an easy problem to solve.

~~~
alrs
Scalability is what microservices give you, at the expense of nearly
everything else.

~~~
edejong
Independant deployment

Multiple languages

A/B testing at deployment fir small services

Less dependency to software specific stack

Security compartmentalizations

Strict programming by interface

Failure isolation

~~~
krainboltgreene
Independent deployment: Rarely needed. Multiple languages: No shared
infrastructure. A/B testing at deployment for small services: Feature flags.
Less dependency to software specific stack: More dependency to homegrown
immature solutions. Security compartmentalizations: Isolated half-assed
solutions with few people responsible. Strict programming by interface: Not
unique to microservices, some people call this "static typing". Failure
isolation: No shared infrastructure, blindsides, definitely not unique to
microservices.

~~~
edejong
Independent deployment: having deployed hundreds of microservices, I can tell
you it is a godsend. Quickly iterating on a specific microservice without
running risk of down-time is useful right from the start. We would sometimes
deploy the same microservice multiple times a day to improve performance or
fix a critical bug. Apart from scaling, this is my number one reason to stay
with microservices.

Multiple languages: the shared infra in this case is your Kubernetes yaml
files and Docker build files, both of which can be shared easily. The rest is
either RESTful or Kafka consume/produce. Python/R/Scala/Java/C#/Haskell/OCaml
can all interface with that.

Feature flags are a possible solution. I worked with them in the past and,
applied correctly, they can offer a similar experience. However, one often
needs more than just a boolean filter: you need to have the logic in your
application to route the requests to, say, two different implementations of
the same interface. Do this on the micro-service scale, and you get a nice SoC
at the proxy level. It moves A/B testing to be part of the infra, not the
application logic.

More dependency to homegrown immature solutions: care to elaborate?

Isolated half-assed solutions with few people responsible: care to elaborate?
My little micro-service component needs the bare minimum of access, which I
can precisely provide to it. No memory is shared, no storage is shared...
Often it is much easier to prove that the system stays within confidentiality
and availability limits. Networking allows me to transparently monitor all
data flowing through my services.

Strict programming by interface vs. static typing. Oh yes, I totally agree
with static typing! Such a big advantage over dynamic typing, read my other
comments on HN. However, there is no static typing across versions of your
same software. Forward compatibility is hard to achieve when all components
need to be upgraded at the same time. I still dread the days when we would
upgrade 'a major version' and all kinds of database tables had to be changed,
causing chicken-and-eggs problems. Not saying that this problem is completely
eliminated with a micro-service architecture, but it forces developers to
think what can be reasonable isolated, causing a higher SoC. It also prevents
the humongous unmaintainable 300+ tables large RDBMSs, which are often the
primary cause of stagnated development.

Failure isolation: I don't understand your reasoning, sorry.

------
throwaway83628
Microservices move tranasactional concerns out of the database and between
service boundaries. If you ever need to transactionally write data to two
different microservices, you need to roll your own rollbacks. And unless you
store this rollback state in a reliable datastore, there's no going back. The
tooling to do this properly, as far as my research goes, does not currently
exist.

I much prefer horizontally scaling a big old monolith backed by a sharding
database like CockroachDb or Cassandra. Same scalability and you get to keep
some ACID semantics.

Concerns about code size are overblown. Facebook's mobile app is utterly
massive and it still runs mostly okay even on weak devices. The maximum
practical code size for a monolithic server side app will probably never be
reached. We're talking maybe 100 million LoC before you run into real
problems, especially if you use a VM lanuage like Java or C# where hot and
cold code can be dynamically swapped out and code is stored in a very space-
efficient fashion

When you reach the scale where the codebase size is an issue you've probably
already several rewrites to deal with such massive traffic volume.

~~~
jpalomaki
And let’s face it - you are never going to get your own rollback logic right.
There will be simply too many edge cases to worry and test.

~~~
throwaway83628
Yes. That's why I'm amazed there isn't some Zookeeper ish system out there for
supporting microservices.

The fact is that microservice tooling is in it's infancy, and shouldn't be
used in production unless you're willing to roll your own everything. I worked
at a place that tried to use microservices+event sourcing+CQRS, predictably a
massive disaster.

I still think the monolith+distributed database will win out . I've never
heard of a time when horizontal scaling was a problem not related to the
databse

------
barbecue_sauce
I often read about (Silicon Valley) companies saying things like "we have a
thousand microservices" or "we have hundreds of microservices" and I really
can't wrap my head around what all of these services do. As someone who has
primarily worked on monoliths, service-oriented architecture seems like an
intelligent idea to me, particularly with regard to scaleability. However, I
can't see getting so fine-grained that you have that many services, especially
considering that from what I've read each microservice should be backed by
it's own datastore. Perhaps its just my own lack of first-hand experience
showing, but it seems like it would eventually devolve into a confusing,
fragmented, and non-performant mess.

~~~
DasIch
What you need to keep in mind is that micro services have a huge fixed cost
but the marginal cost of adding a new one is small.

In other words: Creating or migrating to a micro service architecture is very
expensive but once it’s in place, adding a new micro service is trivial. In
Zalando the goal is that you can do so within half an hour, that is take an
idea, implement it and deploy it to production.

This leads to architectural decisions no sane person would make at a smaller
company. For example let’s say you get data from an external company via SFTP
and you make it internally available, so what do you do?

1\. You create a micro service that polls the SFTP of the supplier for new
files and sticks them into an S3 bucket 2\. You create a micro service that
takes the files from S3, parses, transforms into JSON and publishes events to
Kafka. 3\. You create a micro service that takes those events enriches them
with some other data and republishes new events. ...

Especially when you use Kubernetes, you also start thinking about
infrastructure completely differently. Why use multiple threads or processes
for example, when you can just run multiple instances of your application very
cheaply and temporarily run further instances to handle background tasks?

~~~
batiste
And after 1 year running like this you have 50 micro-services by engineer. All
of them undocumented, poorly named with unclear responsibilities using the bus
to communicate with god knows who... I might be old fashioned by I would take
a monolith over this over-engineered mess any day of the week.

~~~
DasIch
In Zalando, every PR made must be reviewed by at least one other engineer.
Every application must be registered which involves giving it name, a
description and associates it with the team owning the service. APIs that
cross team boundaries must further be reviewed by an API guild, a group of
people that are experts in API design, this also applies to events.

Events go through Nakadi, which enforces a schema and authorization. You can
further tell which services are subscribing to such events and through the
before mentioned application registry who is responsible for them.

Additionally compliance with various laws and shareholder expectations
requires regular reviews, to identify and fix issues such as missing
documentation, monitoring, SLOs, data storage restoration tests (in
production), load tests etc.

The scenario you describe is not possible or allowed. As awareness and
adherence to these rules is also part of performance reviews, it’s also not in
any engineers in interest to do that.

You’re right of course that one needs to be aware of that.

------
dragonwriter
Er, but the description of a “well-architected monolith” here is a set of
loosely coupled components (with specific criteria for where you at component
boundaries) communicating over an external set of message queues, which, while
it doesn't have all the features which define a microservice architecture, is
itself a widely documented, well-known, older (heavily documented in the
1990s, possibly older) alternative to monoliths. I suppose this is being
called a monolith because everything _except the message bus_ is implicitly
jammed into a single process rather than each module being in its own process.
But, even aside from the modularization being different from a monolith,
bringing messaging out of process makes a huge difference compared to even a
modularized single-process solution.

~~~
keithnz
I'd argue you don't need an external message queue. You can use inprocess ones
or an Actor based system.

~~~
taeric
I'd argue the message queue is, itself, likely not needed. Not directly.

I think, ideally, for a system to be successful, you need to understand all
places that you either build up messages, threads, buffers, whatever. It
ultimately doesn't matter which you do. Just don't do too many. And don't make
migrating a solution from one type to another part of your critical path to
launch. Logging, in particular, is something I've grown tired of people
reinventing before they have even launched.

------
red_hare
Can anyone recommend good examples of monoliths in open source? Preferably in
Go?

I inherited a bunch of micro services at my current job with a fairly small
team. My feelings have been that the code had been prematurely micro-serviced
considering the team is so small and every service was mainly just CRUD in
front of then same Postgres instance.

I’ve slowly been demonstrating the benefit of modularlized “sub-apps” in a
single monolith over lots of microservices that all reinvent the wheel. And I
think I’ve convinced them that this is easier going forward. But I’m at a loss
sometimes about what boundaries I should be putting in place such that we
don’t end up with a ball of mud in two years.

~~~
sarabande
Kubernetes is a pretty large open-source Go project:
[https://github.com/kubernetes/kubernetes](https://github.com/kubernetes/kubernetes)

Docker is, too: [https://github.com/docker/docker-
ce](https://github.com/docker/docker-ce)

~~~
threeseed
Is Kubernetes really a monolith ?

It isn't one codebase and when deployed there are multiple daemons running.

~~~
snail_98
People confuse monolith and monorepo all the time. If you have a monolith
where each independent module communicate via queue, like described in the
article, you are so close to having a monorepo of horizontally scalable micro-
services.

------
dave_sid
It’s fashionable just now to hate monoliths, so much so that developers would
probably be afraid to suggest anything other than creating a suite of
microservices for fear of sounding backward or inexperienced. It’s a bit like
if anyone ever dared to suggest that they don’t adopt Agile. You’d probably be
chased out the room by an angry mob.

~~~
anothergoogler
It's fashionable right now to like monoliths. It's "thought leaders" trying to
one-up other "thought leaders," contradicting for sport. And who cares anyway?
Software fashion is cargo cult nonsense pushed by people who probably struggle
to ship anything that's robust or reusable. They're obsessed with keeping up
with "thought leaders" on Twitter and Medium. They fly to speak at conferences
and make a big name for themselves while the rest of us are busy grinding and
limiting the damage they can do.

~~~
xirdstl
It may be fashionable to like monoliths on HN, but microservices is still the
hotness if I judge by the recruiting emails I get.

~~~
anothergoogler
Exactly, microservices are mainstream and boring now. Designing around
services? You must be a pointy-haired boss!

------
iameli
So... keep modules separate, use queues and databases to communicate between
modules, make sure the queues and databases are a separate process from the
monolith.

This sounds a bit less like a monolith and a bit more like a bunch of
microservices that you've welded together in one container. Which is great! If
you're disciplined about maintaining that, it will be very easy to spin off
these individual modules as their own microservices when the time comes.

But I'm not sure that this constitutes an argument for monoliths >
microservices.

~~~
rossdavidh
What is presented here as a monolith is, however, what the word "monolith"
means in current design conversations that I hear in workplaces. Also, I don't
think the article was trying to advocate monoliths > microservices, but rather
more like "it's ok to use a monolith if that works, and at first it probably
will". Because true microservices introduces a lot of infrastructure work at
the very beginning, when you desperately need to be working on code for your
basic product.

------
tannhaeuser
What's a monolith anyway? At this point just a straw man to pitch
microservices against. There are many ways to modularize code; after all,
(class-based) OOP is about code organization via modularizarion. In my
experience, "REST microservices" is one of the worst, as it derives its
working principles from the unrelated problem of loose coupling of web browser
and web servers just because it has to use HTTP for unclear reasons, then
applies these principles incorrectly, naively, religiously, and dogmatically,
while mimicking a two-tier application model that isn't called for. It's
really the mother of all antipatterns.

~~~
hnzix
@honest_update: _We replaced our monolith with micro services so that every
outage could be more like a murder mystery._

------
twodave
Worked for a place recently (and briefly) that claimed to be building a
platform on micro services. When I got there I found that while they indeed
had a bunch of independent processes hanging around they all relied on a
single data source. All introducing micro services accomplished was a LOT more
network overhead between processes and the main (SQL) data store. When you
have a bunch of processes talking to the same data store, you still have a
monolith whether you want to call it that or not, because you lack the freedom
to refactor your schema without changing every service that relies on the
store.

~~~
maccam94
Ah yes, the distributed monolith antipattern.

------
vorpalhex
I agree entirely. Microservices have advantages but they also bring along
severe complexity. Many problems can be cleanly modeled as a monolith - and
they should be. No architecture pattern is immune to abuse.

~~~
monkeydreams
> Microservices have advantages but they also bring along severe complexity.

Worse, often the complexity they bring is undocumented because it lies in the
relationships between applications, accounts, infrastructure, and so on, and
does not lie within the boundary of a single application. Microservices are
simpler to write because you can pretend a lot of the ecosystem does not
exist.

~~~
InclinedPlane
On top of that, microservices often suffer from inadequate tooling. Companies
like Amazon have been working on tooling for their services for literal
decades, most companies have some half-assed attempts at tooling and don't
understand why that's a problem. Consider deployment, for example, how do you
know what's deployed at any given time? Well, the answer is usually something
along the lines of "oh, that's just the head revision of all of the relevant
repos/branches". And what about the staging and dev environments? And what
about logging and history? How much work is it to figure out what code was
running when certain bugs were filed?

~~~
romed
That sounds like a monitoring problem and nothing to do with microservices vs.
monoliths. If you have 10000 replicas of your monolith, how do you know what
version they are running? If you can answer that question then you can also
answer it for 100 replicas of 100 difference services.

------
adamdrake
I run into the microservices obsession very often in the high-growth startups
I advise, so often that I wrote Enough With The Microservices
([https://adamdrake.com/enough-with-the-
microservices.html](https://adamdrake.com/enough-with-the-
microservices.html)).

I typically see people try to push microservices as a "best practice" for
improving the delivery rate of software teams. They carve the codebase into
separate services, but still leave all of the persistence in place so that all
services are communicating with the same DB(s). The result is a tangled web of
interdependent services, plus additional tooling like Docker, Kubernetes, etc.
that actually makes the teams even slower than they were before.

I'm glad to see us as a community getting more pragmatic about these topics,
and realizing that _best practices_ are highly context dependent!

------
shearnie
My angle on building products: Monolith to market.

Break it up and optimise where the sticking points are as customer base and
feature set matures.

~~~
pfarnsworth
It's not that simple, and that's the problem with microservices. You'll learn
that "break it up" means a huge investment in devops, logging, stats
dashboards to understand what the problems are, etc. It's like transitioning
dimensions from 2D to 3D, and that's the trap that most people fall into.

You cannot survive microservices without real-time dashboards and proper
logging to understand the health of your environment, whereas with a monolith,
it was fairly obvious because there's the server and usually a database, and
that's it.

~~~
batiste
All true about monitoring and logging. Is is a huge cost and overhead.
Consider it the other way around: micro-service to monolith. It seems to me it
is as difficult, if not more difficult. Potentially different language or
different build system are used. Different framework might be in place.
Sometimes a merge is completely infeasible without a total rewrite. So going
from micro-service to monolith is like going from 3D to VR. Splitting seems in
a way way easier than merging back.

------
lucidone
I agree with this. However, for whatever reason, suggesting a monolith or
(gasp!) not writing a spa for an app and using traditional ssr html seems to
signal that you're antiquated and old fashioned. I've only been doing this for
3 years and it's ridiculous.

~~~
collyw
Yes this is the problem I am am facing just now (been doing this for 15
years). I care more about writing decent code than chasing trends, but it
means my skillset looks stagnant.

------
halayli
This still looks like a micro service architecture to me, or very close. A
monolith solution would probably be everything in a single process (1 tier).
Queues decouple services, whether the code base includes the consumer &
producer together or are separate doesn't matter, they are still deployed
separately.

It's definitely not black/white, but a spectrum.

~~~
balfirevic
So, in micro-service architecture services don't have to be particularly
small. They also don't need to actually be services. Do words not have meaning
any more?

------
cottsak
Microservices pundits have strategically (or accidentally) engineered the hate
for non-microservice design. They chose the term "monolith" to disparage
anything that wasn't SOA. "Monolith" has a natural negative connotation so
right there, you're winning at the "tech pissing fest" at the bar after work.

The fact is that "monolith" applications can scale, and they can be deployed
as a unit and they can still adjust to varying load using modern cloud
infrastructure.

The enemy to scale, productivity and success isn't "monoliths". It's
complexity! And an experienced and pragmatic developer will tell you that they
fight daily to avoid complexity at every turn. Yes, sometimes it's necessary,
but they weigh the pros and cons on a case-by-case basis to ensure that the
gradient to complexity is always as low as possible.

~~~
edejong
And, how is complexity caused? What are the origins?

It is caused by bringing together unrelated things.

It is caused by violating the single responsibility principle.

So, we isolate state from communication. We separate interface from
implementation. We see as many, where others see one. We try to see the
network of dependencies, where others see a single line of code.

Using this new perception, we find that the large application entangles the
change of (code) state of one part with every other through its deployment.
The static typing guarantees only validate one specific instant in time, but
nothing about the future or the past.

So, take a step back and see the deployment of code as a functional part of
the code. Now the monolith forms complexity and the microservice isolates it
to the minimal surface.

Take it one step further, and we see that the actor model is the exponent of
this idea. Late binding, late dependency tracking, programming by behavioural
contract.

~~~
gfs78
>And, how is complexity caused? What are the origins? >It is caused by
bringing together unrelated things.

It is also caused by wrongly separating things that are closely related and
putting a network or something similar in between.

You cannot reduce software development to a formula.

~~~
edejong
No, so saying outright that microservices are better or worse is just that: a
formula.

~~~
gfs78
No, its a categorical consideration made without the needed context. Basically
an opinion.

------
ilovecaching
I think we're just bad at predicting the future. You can go go fast and sling
code at the wall because the odds of ever reaching FAANG scale is low and you
want to be pragmatic, and then one day you accidentally do hit FAANG scale and
you're in the news every week for security breaches and outages. You can also
do everything DRY and micro-serviced from the beginning, run out of runway and
crash. Or you could get to FAANG scale and realize you need to rewrite
everything because you didn't foresee X, Y, Z requirements and technology has
shifted 20 yards to the left. My approach is the gardener mindset. Think about
organic growth up front when writing the code, but also be pragmatic and start
with a "minilith" with interfaces in the right places.

~~~
kkarakk
if you keep yourself aware from day one about the issues in your
codebase/service and what doesn't scale it is not that hard to switch from
monolith to microserviced is the point of this article i think. there's a
difference between a conscious decision to ship a monolith and code quick
"ship it now" monolith most companies won't reach FAANG,they'll be lucky to
even reach preferred local service

------
pvorb
"Monolith" literately translates to "Einstein" in German, which can't be that
bad. Or can it? ;-)

------
he0001
I think there’s something that people mostly forget. Most of the times we are
compairing microservices with monoliths but forget that almost all monoliths
are much older than whatever microservice someone have recently built. Also
whoever built those mostly have the luxury of not making the inevitable
mistakes you did when you built the monolith. So saying that microservice is
better than a crappy monolith is kind of not true. You can argue all you want
about whatever style but anything well build is still good. And it’s easy to
fuck things up in both scenarios.

------
tln
Undoing microservices at my current job has been nothing but positive.

------
bg4
Both my current employer and last have fallen into this trap. Trying to do
microservices with a small team and moderate to low complexity. Both built
distributed monoliths with a shared core and were spending lots of money
keeping it from falling over. They incur all the costs of microservices with
none of the benefits.

Microservices are a siren song for many small/medium sized companies. What
they need is clean separation between subdomains (composing domain level API
functionality together in the user level APIs to implement business logic) and
clean separation between domain and infrastructure code. There are a lot less
complex ways to achieve this without microservices.

------
tanilama
Of course they are OK. It doesn't matter it is microserivce or monolith, what
matters is how well your architecture executes the principle of separation of
concerns. That is largely irrelevant of what philosophy you are choosing.

------
cristianklein
I don't get it. The article argues that a "good monolith" is composed of a
code base + RabbitMQ deployed in Docker. The code base probably needs a
database too, let's say MySQL. You probably also need to serve static assets
(JS and friends), so an nginx container might be handy.

Isn't this already an application composed of four micro-services: three
micro-services are 3rd-party, while one is developed in-house?

------
macca321
For anyone trying to put together a well architected 'monolith' using C#, I
can recommend
[https://github.com/realvizu/NsDepCop](https://github.com/realvizu/NsDepCop),
which allows you to set up far more granular and useful dependency rules
within your code than standard project references.

------
threeseed
The famous J2EE + ESB style pattern.

Many of us have worked on dozens of these before and sure they work but
microservices were invented specifically to address the serious concerns with
these patterns.

1) It's far too easy to create spaghetti code that spreads across multiple
modules. And because they are so intertwined teams are very reluctant to do
major refactors. Especially when the original authors eventually leave.

2) It's less flexible at scaling. In a monolith you have to horizontally scale
the entire application behind some load balancer. So if you have an Email
concern that needs to handle 100x more load what do you do ?

3) API contracts are far easier and safer to evolve than ESB ones. There are
also clean mechanisms in APIs for handling versioning, capability discovery
e.g. HATEOS, documentation e.g. Swagger, rate limiting, caching, analytics,
billing, authentication etc.

4) Microservices are much easier to reason about, test, document, teach new
starters about and most importantly replace. If I replace a microservice I
just need to verify that the API contract is the same. In a monolith I need to
basically retest everything since there is no guaranteed isolation.

I could keep going on. But not sure this blog post offers anything
particularly insightful in how to deal with the negatives of a monolith
architecture.

~~~
DenisM
It seems that apart from scaling your concerns boil down to enforcing
discipline? Perhaps there are methods of enforcing discipline that don’t
involve serializomg and deserializing a bunch of data several times per
request.

~~~
not_kurt_godel
> serializomg

I realize this was a typo but first thought it was an awesomely-named
serialization library :)

~~~
jacob019
I read it as an opinion on the cost of serializing

~~~
DenisM
It wasn't. It is _now_ though.

------
diminoten
> a complicated microservice architecture

> Microservices are complicated to develop

> Microservices dependencies are difficult

Well, if you say so! Kind of hard to take this article seriously when the
argument boils down to a tautology.

Microservices _may_ be hard! This article contributes nothing to that
conversation, though.

------
the_arun
We need to define - what is a monolith before concluding - Well architected
monoliths are okay.

------
samat
This is quite funny. People are basically saying 'think about your problem, do
not follow the hype' and that feels like a revelation. Says something about
state of the industry, doesn't it?

------
franzwong
It is also difficult to keep a monolith as "well architected" in reality. No
matter what, we should start from a "well architected" monolith first as the
last part of the article says.

------
tomerbd
Didn't he say he runs the async queue consumer in another process? Doesn't it
make it practically another "micro service"?

------
Sophistifunk
This sounds like a great way to get most of the problems of monoliths and most
of the problems of microservices at the same time.

------
eternalban
A reminder that the space of architectural possibilities is not merely a
binary domain of {microservice, monolith}.

------
tvon
What "well-architected" system is _not_ okay?

------
andy_ppp
And arbitrary micro service boundaries are a disaster.

------
thefactotum
> they let development teams focus on delivering features

I agree, but later on, when the team and the codebase grows, you'll need to
split it into smaller parts, and microservices (or any other similar
architecture) gives you some guidance that can be shared across the team/s
making architecture decisions more consistent and providing a common framework
that improve reusability, but it's not an easy path!

------
d3ckard
If you try to differentiate monolith acceptability based on "quality of
architecture", you really have never understood why they are hated in the
first place.

~~~
vorpalhex
No architectual pattern can survive a lack of maintenance and grooming.
Sprawling microservices written in a dozen different languages can be worse
then a mangled monolith.

~~~
maxxxxx
I always say if you can't design a monolith then don't bother with
microservices. You shouldn't use microservices to cover up for a lack of
design skills or a lack of communication between teams.

~~~
xab9
Every man is an island in the world of microservices.

Look, my microservice is clean and nice and has a 100% test coverage, I
couldn't care less if you can't communicate with it from yours. Solve it
somehow.

Now get off my lawn and let me rewrite the whole thing in scala.

