
Microservices Are Something You Grow Into, Not Begin With - fagnerbrack
https://nickjanetakis.com/blog/microservices-are-something-you-grow-into-not-begin-with
======
adamdrake
Most of the time, I've found a push to microservices within an organization to
be due to some combination of:

1) Business is pressuring tech teams to deliver faster, and they cannot, so
they blame current system (derogatory name: monolith) and present
microservices as solution. Note, this is the same tired argument from years
ago when people would refer to legacy systems/legacy code as the reason for
not being able to deliver.

2) Inexperienced developers proposing microservices because they think it
sounds much more fun than working on the system as it is currently designed.

3) Technical people trying to avoid addressing the lack of communication and
leadership in the organization by implementing technical solutions. This is
common in the case where tech teams end up trying to "do microservices" as a
way to reduce merge conflicts or other such difficulties that are ultimately a
problem of human interaction and lack of leadership. Technology does not solve
these problems.

4) Inexperienced developers not understanding the immense costs of
coordination/operations/administration that come along with a microservices
architecture.

5) Some people read about microservices on the engineering blog of one of the
major tech companies, and those people are unaware that such blogs are a
recruiting tool of said company. Many (most?) of those posts are specifically
designed to be interesting and present the company as doing groundbreaking
stuff in order to increase inbound applicant demand and fill seats. Those
posts should not be construed as architectural advice or _best practices_.

In the end, it's absolutely the case that a movement to microservices is
something that should be evolutionary, and in direct need to technical
requirements. For nearly every company out there, a horizontally-scaled
monolith will be much simpler to maintain and extend than some web of
services, each of which can be horizontally scaled on their own.

I also wrote [https://adamdrake.com/enough-with-the-
microservices.html](https://adamdrake.com/enough-with-the-microservices.html)
as a way to communicate some of this, including some thoughts on when and how
to structure a codebase (monolith) and when it might make sense to start
moving towards microservices, etc. There are cases where it's reasonable (even
advisable) to move towards microservices, but they are rare.

~~~
geezerjay
I don't believe it os reasonable to portray microservices as the result of
incompetence and blame-shifting.

Microservices are actually a very basic and fundamental principle of software
engineering: separation of concerns. If your system is extensive enough so
that it covers multiple independent concerns and your team is large and
already organized into teams focused on each concerns then it makes technical
and organizational sense to divide the project into independent services.

~~~
taneq
They're subject to a clear limit, though. The more micro you make your
services, the less they resemble operational units and the more they resemble
primitives from which your actual system is built, sort of like an inner-
platform effect. And then you have to debug interactions between
microservices, with all the overhead that entails.

------
lbriner
I agree that microservices is the new "must have" technology but actually it
isn't a great deal different from a monolith. The monolith can have separation
between services and still requires interfaces to work between them.

As others have said, microservices bring a lot of baggage that you might never
have seen before (i.e. big learning curve) and the myth of isolated changes is
just that, a myth. Unless it is some low level thing, you cannot change it
without impacting other services and this is no different than a monolith.

Like the article yesterday about OOP, the same principles exist to write a
good application whatever you use to do it.

~~~
kabes
Indeed. It just replaces internal calls between services of your monolith with
flaky and slower network calls.

~~~
sixdimensional
Counterpoint: if network calls weren’t flaky and slow would it make a
difference in deciding whether to separate modules via a physical machine
boundary?

~~~
danmaz74
But network calls ARE inherently flakier and slower. What good does it to
imagine they weren't?

~~~
sixdimensional
It helps demonstrate where additional investment and development might be
warranted. If we have hit a physical limit in networking, then that is one
thing - but if we are only hitting an artificial limit because our technology
and infrastructure is not sufficiently advanced - then this problem is
actually showing an opportunity.

As an architect you have to sometimes ignore constraints to understand if the
final picture you would assemble makes any sense. If the final picture you
assemble makes sense, then working backwards through the limitations, to find
out, are these really limitations or are these opportunities to innovate?

That's my thought as to why you would imagine they are not a limitation. To
aid in brainstorming, innovation and identify opportunities for improvement,
or alternative solutions you would not have seen if you simply accept the
bottleneck as a given.

~~~
spdionis
As GP said the network is inherently flakier and slower and yes, we are very
close to the physical limit.

------
kcsomisetty
Having worked in a payments company, where SLAs can be very demanding,

We broke our monolith server into microservices, and realized that we broke in
to too many pieces as our SLAs broke. (every microservice you add to your
usecase adds a small but fixed cost)

and finally decided to convert some microservices into libraries to save
milliseconds and bring down our 95th percentile, I completely agree with the
premise of the article.

never start with microservice, start with monolith with enough flexibility and
inbuilt abstractions which can allow you to replace an abstraction with a
monolith.

------
vectorEQ
people jump into this because of shit processes like agile which push for
incremental and iterative development processes instead of thinking things
through properly. usully just to be able to have easy deliverables and easy
reporting to upper management about the epic progress that is made. all the
while product quality usually is degraded to a point where customers will
start to feel it badly. always the same dumb excuse is used that tech is
changing so fast. but really, it's only changing so fast because people invent
retarded processes which move too fast. you don't need to keep up with every
innovation if you have a good quality product. you only need to keep up with
this if you require all the latest buzzwords in your product because without
them you are unable to sell your piece of junk. /endrant

~~~
yakshaving_jgt
What drives me crazy is that what you're saying is absolutely spot on, and I
share the sentiment, but this kind of criticism is usually tone-policed into
oblivion.

------
arendtio
There are many ways to slice an apple.

Sometimes it is a good idea to build something as microservices, but you just
have taken the wrong approach, and therefore it is a pain in the __*. So
slicing it a different way might still be a microservice architecture but feel
much better.

Recently I thought about setting up a Firefox Sync server. The first bumper
was when I learnt that the sync server has a dependency on the accounts
server... But the full-featured accounts server, in turn, consists of a bunch
of services of its own [1]:

\- fxa-content-server

\- fxa-profile-server

\- fxa-auth-server

\- fxa-oauth-server

\- browserid-verifier

\- fxa-auth-db-mysql

After seeing that I decided to tackle that project another day.

For Mozilla that architecture might be perfect, but for most people who just
want to run a separate server for <10 people, that architecture is just a
burden.

[1]: [https://github.com/michielbdejong/fxa-self-
hosting](https://github.com/michielbdejong/fxa-self-hosting)

~~~
rfk
FWIW, as a developer on the Firefox Accounts team, I strongly endorse the
sentiment of this article. We've occasionally found ourselves merging
microservices back together because the abstraction boundaries we designed up-
front weren't working out in practice...

------
jdc0589
I have a _slightly_ different opinion. Start with a mostly monolith, sure,
that makes sense. But also start off with just _one_ separate microservice for
something important. It's important that you establish good patterns for
integrating services in to your codebase early on. Its really easy to write a
monolith without any thought of external service abstraction, which makes it
WAY harder to do down the road if you decide you need to.

------
BillinghamJ
I think you can selective. We started with ~5 services all built fairly ad-
hoc, splitting on sensible boundaries with the goal of never having a "mega"
service.

This means it has been reasonably easy over time to fully replace them on an
individual basis with more mature systems without changing the API design.

Now we're 3 years in with ~40 services and the approach has served us very
well.

Definitely agree you shouldn't start with a ton of services, but I think you
should definitely start with more than one. The jump from monolith to service-
oriented thinking is a huge one. But the jump from a few services to more is
much easier.

~~~
collyw
> Definitely agree you shouldn't start with a ton of services, but I think you
> should definitely start with more than one. The jump from monolith to
> service-oriented thinking is a huge one.

I can't get my head around this.

Why should you start with more than one?

What is so different about "breaking your application into services" and
"breaking your your application into appropriate modules / classes"?

If those need to scale then you should have an interface that you can expand
to a micro-service.

As another poster said "It just replaces internal calls between services of
your monolith with flaky and slower network calls. "

~~~
ex-aws-now-goog
What is different about breaking an application into services is that because
services run as different processes: * you have an immediate natural failure
domain (the process) as well as resource isolation between services, *
services can be updated independently (something that is done many thousands
of times every day at companies like Amazon or Google), * a corollary of
independent updates is that services can be tested independently and new code
can be "canaried" by initially deploying only a single instance of a service.

The statement that service orientation "... just replaces internal calls
between services of your monolith with flaky and slower network calls" is
correct in that network calls are flaky and slower but incorrect in its
assessment that you gain nothing from using services.

~~~
collyw
I'll give you that you can deploy services separately, but the other
advantages that you give could be accomplished with automated testing - that's
kind of the point in unit testing to test components independently.

The vast majority of people aren't working at Amazon or Google's scale despite
developers seeming to think that they need to work the same way.

------
sixdimensional
I am in the middle of implementing a POC/MVP of a greenfield micro services
architecture that I was assigned to do at work.

My background is more monolithic and some SOA, so I have had to adapt my
thinking to try to make this work.

I am an open minded architect and always willing to explore what the good and
bad takeaways are from a given approach.

I think that microservice architecture gives us a chance to think about what
would happen if we thought of an ecosystem of applications fully decomposed
into a fabric of services.

The first and hardest thing I have encountered so far, was trying to
understand the right decomposition into ideal smaller units, something that is
nearly impossible without understanding the requirements in full up front. I
am not sure you can easily identify your service/domain contexts and
boundaries (a la DDD) perfectly enough when you are doing agile development
and the microservice architecture is intended to be used by many applications.

However, there is a caveat- if you build modules to be smaller it is easier to
reason about what each one does by itself. So that part actually fits in with
Agile well.

Also, if you, for a minute, imagine that network / machine boundaries didn’t
have implications (latency, retries, etc.) and were as reliable as service
calls, and if you imagine that we had reliable distributed two phase commit
(it can be done, but all subsystems involved have to understand transactions
and someone has to coordinate it)... I at least can start to see a picture
that works.

I believe microservice as simply to be an old idea (build in a modular small
form) in a new light, and I think it is part of us trying to evolve our system
development and architecture further.

Don’t look at microservice as a panacea nor fad. Look at the problems it
raises as opportunities to improve the problems it highlights, and then
suddenly all of this might make sense as a scaled up architecture that can
start small and scale smoothly to big in the future.

I believe it’s all part of the same journey we all have been on, developing
systems that go from local, to global and maybe someday, beyond.

~~~
sixdimensional
To add, one other problem that still needs solved in this picture is data
federation - and if you solve the network problem and IO limitations fall
away, you might actually be able to do crazy things like make joins across
distributed systems work, as well as distributed transactions. We already do
this with some planet-scale databases, but we are early in this - and it might
need to work in the application layer outside of databases too.

------
erik_landerholm
We are finishing up a 2 year migration out of a data center to Aws and a
complete rewrite of a Frankenstein Soa (of sorts) to a couple of monoliths
__.I was basically in charge of choosing the tech selection (we wanted to
minimize tech stacks until we could get a handle on it) and the “how.”

A monolith made perfect sense as there was nothing salvageable, and I mean
nothing. And the traffic requirements were definable, growing predictably and
not that large. Pretty bag for a medium-sized enterprise.

Picture a company that has no tests, little documentation, 4500 line stored
procedures (2000 sPROCS in total containing all the business logic), one data
center and no dr, and they would deploy once every 8 days...in 2016! Oh, while
making 300M a year with 600 employees.

We are weeks away from turning off the data-centers, have great test coverage,
ci/cd; we deploy hundreds of times a week, site is much faster. We were able
to combine our front end react tech to gives 99% code reuse in desktop/mobile
web and native mobile.

The company makes more money than ever and we have made huge conversion wins
by getting our shit together and doing normal, smart product things, while
redoing the culture, software and infrastructure.

I hated fighting with these “do-nothing” people that had read articles about
SOA/uServices/message passing arch/etc. the worst are the ones that can’t
avtually do anything. They are usually the loudest.

In reality we use three different architectures, but the core business and
logic is in one single backend DB and rails backend and it’s beautiful.

We have about 100 developers. We had a couple of issues with people stepping
on each other at first, but with some structural changes to our app and some
automated process (oh and letting 40ish people go while hiring new people) we
solved it.

I can’t wait to burn the old servers to the ground. I’m leaving our so much
detail. One day I’m going to write the whole story along with my two other
partners who really spearheaded the change.

* front end monolith talking to a backend over REST apis. We have internal monolithic applications to help us get our job done. And We have a message passing system called Wormhole and a single uService. Simple...

~~~
i_made_a_booboo
I'm dying to read the whole thing. Please.

------
harel
Bottom line is that it's all a case by case basis. However I'll always warn
against slicing microservices too thin. Each slice is a moving part outside of
the machine and therefore brings in additional risk. I recently
refactored/rewrote a monolithic project into a few fairly chunky services.
Each one is sliced by a broad context. The only reason I did it was because
the monolithic app required separate physical deployments per client due to
data sharing restrictions and the service model (I won't call it micro) allows
sharing of the data I'm able (and should) share between them. Perhaps we need
a name for the model in between monolithic and "micro"-services. Maybe Macro
Services?

~~~
eropple
The term used before "microservices" got trendy was "service-oriented
architecture," or SOA.

So this isn't exactly a new idea. ;)

~~~
harel
Nope. Nothing new here. I remember SOA very well as the buzz word du jour back
then. It sounds less cool than micro services though. At least we got our buzz
words through the PR & Marketing departments in this decade.

------
Aissen
IMHO, the monoliths vs microservices debate is akin to monorepos vs multi-
repos: they are both strategies used to share work when your organization
grows. Both can work well, depending on your tooling and organization.

But do not forget that those abstractions layers you add, while very useful
(say, for release velocity), might also be a direct application of Conway's
Law:
[https://en.wikipedia.org/wiki/Conway%27s_law](https://en.wikipedia.org/wiki/Conway%27s_law)

Which means that refactoring some code, might sometime require refactoring
your organization, so if you lack the ability to do that incrementally, you
might converge to an ossified system that stops evolving.

------
yakshaving_jgt
Interesting that the article mentions Shopify supporting over 600,000 users
with a Rails monolith.

At my day job, one of the justifications for us adopting microservices is that
we want to horizontally scale.

We have fewer than 8,000 users.

Hubris, eh?

~~~
ovi256
The load per user can be widely different in different application. We don't
have a great measure for that, one cound use a combination of requests per
user per day, and the sum of CPU-seconds used to serve them. The sum of CPU-
seconds should contain the periodic (e.g. cron-like, not directly request-
answering) tasks too.

At one extreme, you have applications that need horizontal scaling from day
one (Scientific computing). At the other, a monolith serving 10^6 users from a
single app instance.

~~~
yakshaving_jgt
Yes, that is a reasonable response and I should have preempted that.

For context: the product at my day job does something likely at an equivalent
level of complexity to Shopify. It's just another SaaS business that handles
payments, invoicing, etc. If anything, Shopify is _more_ complex.

~~~
ovi256
So the fact that Shopify succeeds doing that in Rails, not in C with assembler
optimized code, is even more impressive!

------
majidazimi
Why not? I mean we don't use micro-services for what it is supposed to do. The
application would perfectly be a monolith. We do it, just because it lets us
experiment newer technologies in not-so-important services in a smaller scale
without undergoing major re-work since when the change is big, everyone in
management layer understandably becomes conservative.

~~~
microwhat
Sounds like resume-driven-development.

I worked at a company with this disease before. The system was an abomination
of vastly different technologies over the years stitched together loosely.

Development was slowed substantially by having such a mess and the company
couldn't move fast enough to compete so the startup died. Usually tech isn't
the reason for a startup's death. In this case, it was.

~~~
majidazimi
> Sounds like resume-driven-development.

Sure. That's one of the responsibilities of a team lead: to help team members
to work and gradually build up their CVs. I want my team to experiment new
stuff and learn while working. But I also want to limit the risk boundary. The
whole reason why younger people are leaving dinosaur companies is that no one
in management layer lets juniors experiment and fail. End of the day junior
devs also want to improve and develop.

~~~
asknthrow
Nah, your job is to lead the team in the most effective direction in order to
fulfil business objectives, not build resumes.

~~~
ex-aws-now-goog
Your job is whatever you agreed to when accepting that job.

Some companies require managers to aid in the technical development of
employees, some don't. Some provide a lot of latitude in how that's done, some
don't.

~~~
eropple
_> Some companies require managers to aid in the technical development of
employees, some don't._

It's not about what a company "requires". It's about the moral duty you take
on when you manage people.

~~~
ex-aws-now-goog
I'm not sure why you think that striving only to achieve business objectives
could be considered to be a moral duty. Are you perhaps perhaps thinking of
fiduciary duty?

If a company decides that technical development of engineers is good for
retaining engineers and you as a manager refuse to do that, then no moral
argument is going to help you when you get dinged in your performance review.

edit: Upon rereading the thread, I suspect that we may agree more than we
disagree. My comment was directed at asknthrow's comment and I wanted to make
the point (which other posters have more eloquently made in the meantime) that
if technical development is part of your job as manager, you don't have a
choice in the matter and your job is not just "to lead the team in the most
effective direction in order to fulfil business objectives" (to quote
asknthrow).

~~~
eropple
For sure. To be clear, I mean that _regardless of what your bosses say_ you
have an obligation to the people you manage. Obligations do not only run
upward. (This is something bad managers often do not understand.)

------
jacquesm
Microservices, test driven development, Agile, 4GL and so on. It's all the
same thing: a technique that is applicable some of the time but not all of the
time that ends up getting a bad rap because the people promoting them tend to
come from the theoretical side of the street, and they see the subject matter
as their new revenue stream. They will then promote it to be used even when it
isn't applicable.

A web based service can be as messy or as clean as you want no matter whether
the underlying architecture is a monolith or a bunch of microservices. I don't
like the 'micro' in microservices to begin with, to break up a large and
complex problem into multiple smaller problems that are each simple to solve
is a core principle of programming. If you take that to an extreme you end up
with services that do almost nothing and then you have a communications
problem (or at least, you will have one in most environments you are likely to
encounter). If you glue everything together in on giant hairball you don't
have the comms overhead but you have a cognitive overhead in trying to
understand it all.

Like with everything else: there is a happy medium: services that are easy to
understand because they do not have horizontal ties to other parts of larger
whole, enough isolation to help you with debugging, not so much isolation that
you end up doing remote requests for data that should have been nearby.

Everything in moderation.

As an illustration of 'microservices' done well: I worked - the last time I
had an honest job+ - as a programmer on a message switch for KVSA, a company
that brokers shipping capacity. Super interesting job, even more interesting
architecture. Right from day one (contrary to the article title!) it was
decided the system was too complex to tackle as a monolith. The reliability
demands and the latency requirements led to the base system being built on top
of QnX, a soft real time Unix like operating system with a micro kernel. Since
in a microkernel environment message passing and service oriented
architectures go hand-in-hand the technique percolated through to the
application level, which ended up being a series of queues and 'admins' (QnX
parlance for a daemon or a service) handling the inputs from these queues and
effecting transformations on those inputs resulting in new outputs or side
effects (such as a fax or a telex being sent). The system worked flawlessly,
had a very high degree of redundancy built in and it most likely would have
never made it to production if it weren't designed like this from day #1. For
that particular use case it was ideal.

\+ in 1993, if you're wondering whether microservices are something new you
have your answer.

~~~
Novashi
>It's all the same thing: a technique that is applicable some of the time but
not all of the time that ends up getting a bad rap because the people
promoting them tend to come from the theoretical side of the street, and they
see the subject matter as their new revenue stream.

Also because we've created an industry where everyone must stay up-to-date, so
if anything gets traction, suddenly people start getting worried that those
things are not on their resumes.

~~~
i_made_a_booboo
Which leads to Resume Driven Development driving choices rather than logical
debates where merits and trade-offs are considered.

------
INTPenis
I grew out of microservices because it felt like I was doing the same
boilerplate REST service over and over.

So I made a modular REST API service that could load plugins. The plugins can
contain anything from simple endpoints to database schemas with sqlalchemy.
All this is loaded into the main app at runtime.

So the main app can handle authentication against LDAP for example while all
the various deployed microservices can have their own roles.

~~~
lmz
So a Python version of a J2EE app server?

~~~
icebraining
Or a framework like Django.

~~~
collyw
We love to reinvent wheels in this industry.

~~~
__comrade__
And the result generally looks more like a square than a circle

------
js4ever
What I love about microservices is isolation and forcing you to do thing well
from the beginning. Monoliths tend to become horrible to maintain after few
years. On the opposite change one small 50 lines microservice is a lot less
risky!

~~~
IMTDb
What I love about monolith is coherence and forcing you to do things well from
the beginning. Microservice mesh tend to become horrible to maintain after a
few years when no one really measure which components will be impacted by a
single change. On the opposite, change one small 50 line function and your IDE
will happily show you all the calls to that specific function.

~~~
hoffs
Just like you have tests between monolith modules you can have integration
tests between microservices

~~~
joshschreuder
The more layers you are testing, the slower and harder it is to write tests
and the feedback loop is way longer also.

~~~
Arqu
Depends how you do it. Having a sane communication model/interface between the
services allows you to test it in two ways: 1) You test the internal structure
with unit tests 2) You test changes to the API contract with E2E tests Both
are fairly straightforward once you set it up properly.

Same goes for the monolith, assuming you do your work on following somethink
like the SOLID principle, it is easy to test piece by piece. The only thing
here is that the interface contracts are internal to the codebase vs external
to other codebases. (You might argue the last point actually forces you to
write a more coherent API contract in both situations)

------
barbecue_sauce
I don't like the phrase "microservice" because it now has a certain amount of
baggage, similar to "service oriented architecture" which it was meant to be
somewhat of a counter-point to. Whereas the issue with SOA was its association
with maligned/feared technologies (SOAP, WSDLs, CORBA), the issue with
microservices is the implied granularity. SOA was a good idea, but people
(particularly in start-ups) don't want to say they're doing SOA because it has
old-school, corporate connotations. On the other hand, the granularity of
microservices seems too extreme for what most products would actually need but
the concept is associated with more modern technologies which are attractive
to developers, like gRPC or Avro or Kubernetes (or even something as simple as
HTTP). So I would say the most pragmatic approach for a greenfield web product
(rather than a corporate IT integration) is have a fairly standard core
(probably a REST API, a server-side MVC framework, or a GraphQL backend if
you're nasty) and factor out services that make sense to the team (maybe a
service that handles push notifications, or a service that does image
processing, or a service that is the secret sauce of your product) because
they need to scale independently or handle async/computational tasks that
should have dedicated resources or they pull from a data source that is
orthogonal to the rest of the system. You need to strike a balance between
"micro" and "service".

There is this idea that you either have microservices or you have a monolith,
while its really more of a gradient. I guess what I'm advocating for is
"modern service-oriented architecture" or "chunky services" vs
"microservices"; reasonably sized, well-considered services that use modern
technologies for inter-service communication.

------
z3t4
There's trade-off's. They are using a fairly complex CI while with micro-
services you release each service individually. It's hard to turn a monolith
architecture into a architecture with micro-services. So it all depends on
what works best for you. The idea with micro-services is that with a much
smaller service - development is faster and cheaper, you can for example
rewrite the entire service, use different software stacks (the best tool for
the job), etc. Where as a total rewrite is not feasible in a monolith.

~~~
yakshaving_jgt
Why do you believe development would be faster and cheaper? Because the
individual services are smaller?

Come on. The system is as large and as complex as will be necessary.
Separating components with network calls doesn't make them any less
interdependent.

~~~
z3t4
There's a saying that if it takes one man one year to build a wall, you hire
20,000 workers and the wall would get built in a couple of seconds. That's the
monolith thinking. Now if we make several small teams, and each team build a
very tiny wall anywhere they like, each team could iterate faster, and quickly
rebuild that tiny wall if needed, that's the thinking of micro-services. The
later plan is of course not so smart if the wall is intended to stop people
from entering, so not all systems are a perfect match for micro-services.

~~~
yakshaving_jgt
Your allusion to The Mythical Man-Month is completely orthogonal to the debate
between monoliths vs micro-services.

It's just not at all relevant.

------
partycoder
The argument here is that microservices are another level of code reuse, with
their own encapsulation.

But microservices are also about coupling: just have a self-contained service
that does one thing.

~~~
spreiti
> But microservices are also about coupling: just have a self-contained
> service that does one thing.

What stops you from creating a module inside a monolith with an interface that
provides a self-contained service that does one thing?

~~~
partycoder
You can. But one day, some 10xer will be short on time and will duct tape your
module with 10 other modules.

~~~
hderms
The newish argument for microservices is that they enable compositionality, so
wouldn't that same hypothetical apply? I.e. some 10xer is short on time and
glues a bunch of microservices together and now you have the same problem but
worse because there's no IDE allowing you to trace the code?

~~~
i_made_a_booboo
You have a problem. You decide to use regular expressions to solve it. Now you
have two problems.

You have a problem. You decide to use microservices to solve it. Now you have
ten problems.

------
colemorrison
I agree if you have no idea what you're doing - which seems to be the case for
many developers starting new projects stuck in the paradox of choice.

But like anything else, if you understand the toolset, ecosystem, and have the
experience, it can take far less time than esoteric documentation and
conversation would have you believe.

I always begin with this pattern, but it's because I've acquired so much
experience and know-how with it that it's a quick upstart. However, this
didn't come with any ease. Most want to just dive into really myopic course
work or tutorials that are "just examples" and "shouldn't be used in
production." The WORK to understand it is getting each nuance under your belt.
It's just like any other skill set - it takes patience and deliberate effort.
Documentation spelunking and trial / error experiments.

That being said, under the fire of a manager, timeline of capital, or just the
raw impatience inherent to humans we wind up falling back to what's safe, what
has plentiful easy-to-learn patterns, and listen to all the other folk who get
50% through, stop, and then just spin up terribly organized monoliths.

------
linkmotif
This article and articles like it presume some magical workforce you can hire
that will transform or organically evolve your application into a microservice
ecosystem. But the fact is that people who know how to execute a microservice
architecture, muchless willing to work on your particular budding application
are few and far between. So if you don’t know how to build microservices, it
seems really hard to start with microservices by factoring a live running
application while you are also simultaneously trying to keep that application
up and functioning and feature developing in order to monetize it. Wow does
that sounds difficult.

So it makes more sense to me to build out from microserves—they can be
embedded in one JVM or whatever—so you know how to organically evolve and can
focus on monetizing your application.

------
caseymarquis
You really can get all the benefits of popular architectures without going off
the rails!

Don't start out with a DI framework, use poor man's DI (ie 'passing stuff
in').

Don't start out with microservices, use (poor man's) DI, ban all public
static/global variables, and segregate code into separate processes with
public 'interfaces' (but don't use actual interfaces until you actually need
them! 1 interface per class is an antipattern!). These can all run in an async
process pool you build, which can monitor bottlenecks when you get to that
point. You can then (years later) easily break an internal service into a
microservice when the trade off makes sense.

I'm obviously static typing/oop focused, but there's a version of this which
applies to any paradigm.

------
scarface74
You should always start with domain specific microservices. Those
“microservices” shouldn’t be out of process services necessarily. They can
just as easily be in process “domain services” in a monolith that are only
accessed via an interface where each module is treated as a black box.

------
darth_mastah
I mostly agree with the article except the part where the author plays down
the architectural considerations during project inception.

> Right now it’s just me working on the project, and you can be sure I just
> cracked open my code editor and started writing code on day 1.

It's definitely fun to start with writing code, but in my view it may be more
efficient to pause for a moment, understand the problem and find the right
solution for it. Then start writing PoC code, which can be refactored at a
later stage. That's just pragmatism - lots of code will go to the bin anyway,
but at least we give ourselves a chance to have a longer and happier run with
it before that happens.

------
arunmk
When making generic rules one should provide a lot of context. I have found
that a fairly large rearchitecture is needed to move from a monolithic product
to something with microservices. It is not something to grow into that way.

And the technical reasons to move will be mostly for fault tolerance and
resiliency (you don’t want your whole service to go down because a small
widget failed somewhere). Of course this does not come for free.

Basically it’s not that one is better than the other for all cases. This is a
case where people should consider many things including non-technical aspects
before making sweeping statements or decisions.

------
deltron3030
Can't you have both in a way? A monolith that's glued together by an
"interface language" (e.g. GraphQL), that can be broken up by "ejecting",
removing the glue code?

------
chuqdennis
This is an interesting read, and thanks for sharing. While keeping things
monolithic is an efficient, worry-less and simple approach to architecting a
product to maturity; what would you advise if it will take as much work or
greater to break it down micro-services; 1\. To continue anyways or 2\. Find a
mid-point in the life cycle to break things down or 3\. Have a deep thought
about the future of the project at the beginning (then decide)?

------
karandwivedi42
I am just starting to develop web apps. Is
[JAMStack]([https://jamstack.org](https://jamstack.org)) + Lambda functions
(AWS Lambda) a good place to start with?

Since Lambda functions are similar to microservices, I am now confused if I
should stick to simpler backends or full stack instead of JAMStack.

~~~
spdionis
Is that a joke website or serious?

~~~
karandwivedi42
Serious. It is a concept by the creators of Netlify.

------
someguyontheweb
I agree with writing a lot of code being the way to write better code, but as
soon as I encountered the part about "absolute and total intent to replace
almost everything you write with better code once you start experiencing real
problems first hand" strikes me as not possible in every environment.

If you are writing your own monolith from a basement and are a single
developer, sure. Once you have founded your company and made your millions you
can decide what, where, and when to change in the code. However, for the vast
majority of people who do professional development it is just not plausible to
suggest that you create every project as a throwaway.

Because in corporate development, once a project works (even a low percentage
of the time or with major problems) it can and often will continue its life
forever. Greenfield development has a different process in most places than
maintenance / sustaining, and most people will find that making any reasonable
structural changes to a legacy / monolith / inherited code base will take
years of mostly political arguments because management will be unable or
unwilling to recognize the writing on the wall.

Analysis paralysis is obviously a problem as well that exists on the extreme
end of the other side. However, I believe actually prototyping and testing
early in the cycle is the best of both worlds: you get both the ability to
respond to problems early in the cycle because you're exercising the code
already, and the process will not cripple you from making those changes.

I agree that writing a lot of code is the cure, but please, for the love of
all that is programming, stop insisting that every early prototype makes it
into production with their awful duct tape and bubble gum patches intact.

Break the problem down early, learn some of the finicky bits of the
technologies you've chosen, and be pragmatic...but insisting on taking your
first (often terrible) crack at the problem directly into production where
you'll be stuck on it for possibly a decade is pretty bad advice in most
environments I have developed in my professional career.

It's a recipe that'll often get you stuck troubleshooting irritating design-
induced problems for years to come or hopping to a different company.

There is a middle ground between no design and spending years on whiteboards
and blogs before writing a single line of code...that middle ground is what
needs to be mined instead of constantly taking an extremist stance.

But hey, this is corporate development...so the loudest voices and most
extreme opinions always seem to win out.

------
cphoover
There is a lot of tooling for getting started with microservices now-a-days.

------
joegaebel
www.appcontinuum.io

------
madeuptempacct
My problems with microservices irl:

1\. Sharing models - the models can be moved out to another repository or a
NuGet package, but guess what happens when you have to modify them?
Inevitably, devs duplicate models.

2\. Debugging across five different code bases - have fun changing all the
environment variables to point to your local every time, or running five
different applications at the same time for local development.

3\. Docker and Kubernetes add a LOT of overhead.

4\. Multiple front-end apps combined into one "coherent" site always leads to
routing problems...and token management problems.

5\. Web Components cause bloat by pulling in web component scripts and the
fact that each web component needs to fit the style of the whole site. Since
shadow dom is isolated, each component pulls in styles again - slow. Again,
debugging and checking in web component code is a pain.

6\. Finally, siloing is inevitable.

Imo, this doesn't make sense at all for a smaller web app.

~~~
spdionis
Is duplicating models that big of a problem? Just an honest question, hoping
to get more answers/opinions besides parent's.

~~~
madeuptempacct
It's a good question. Going to let others answers. My tldr opinion is "Not
really, but code duplication any time, but especially across repos can lead to
hard-to-troubleshoot errors".

