Live data from Hacker News

Microservices are a tax your startup probably can't afford

nexo.sh

191–200 of 272 posts

Re: Microservices are a tax your startup probably can't afford

#191
post #154

Earlier quoted context omitted.

> They only had a few hundred MAUs Way too many companies believe they're really just temporarily embarrassed BigTech.

Bad software dev. degrees that focus on fancy architecture that brings nothing to the table except overhead.

I don't remember one solitary lecture on CI/CD, microservices, or even just deployment in general, in Uni. The closest that our comp. sci. classes ever came to touching on anything but the code itself was making us use SVN.

Re: Microservices are a tax your startup probably can't afford

#192

Earlier quoted context omitted.

1 team supporting multiple services is not great, but a monolith with more than 50 developers working on it (no matter how you split your teams) isn't great either. That's why I don't like the term "microservice", as it suggests each service should be very small. I don't think it's the case. You can have a distributed system of multiple services of a decent size. I know "services of a decent size" isn't as catchy as…

> but a monolith with more than 50 developers working on it (no matter how you split your teams) isn't great either. Why can the game industry etc somehow manage this fine, but the only place where it's actually possible to adapt this kind of artificial separation over the network, it's somehow impossible not do it beyond an even lower number of devs than for a large game? Suggests confirmation bias to me. The main p…

Consider that game programmers are generally more skilled than enterprise devs due to tougher domain constraints and role scarcity.

Re: Microservices are a tax your startup probably can't afford

#193

Earlier quoted context omitted.

Because the network call turns the rule into a law.

This is also why app backends don't really need statically typed languages, no matter how big the company is. You have a well-defined API on the front, and you have a well-defined DB schema on the back, that's good enough. The static typing makes even less sense at finer code scopes, like I don't need to keep asserting that a for-loop counter is an int.

Statically typed languages, when used correctly, save engineering time both as you extend your service and when thing go wrong as the compiler helps you check that the code you've written, to some degree, meets your specification of the problem domain. With a weak type system you can't specify much of the problem domain without increased labour but with a more expressive type system (and a team that understands how to use it) you can embed enough of the domain specification that implementing part of the business logic incorrectly or violating protocols turns into compile errors instantly rather than possibly leaking to production.

As for your comment on `any`, the reason why one doesn't want to fall back on such is that you throw out most of the gains of using static types with such a construct when your function likely doesn't work with `any` type (I've never seen a function that works on absolutely anything other than `id :: a -> a` and I argue there isn't one even with RTTI).

Instead you want to declare the subset of types valid for your function using some kind of discriminated union (in rust this is `enum`, zig `union(enum)`, haskell ADTs/GADTs, etc etc) where you set a static bound on the number of things it can be. You use the type system to model your actual problem instead of fighting against it or "lying" (by saying `any`) to the compiler.

The same applies to services, APIs, protocols, and similar. The more work the compiler can help you with staying on spec the less work you have to do later when you've shipped a P1-Critical bug by mistake and none of your tests caught it.

Re: Microservices are a tax your startup probably can't afford

#195
I see this a lot ("if you are a startup, just ship a monolith").

I think this is the wrong way to frame it. The advice should be "just do the scrappy thing".

This distinction is important. Sometimes, creating a separate service is the scrappy thing to do, sometimes creating a monolith is. Sometimes not creating anything is the way to go.

Let's consider a simple example: adding a queue poller. Let's say you need to add some kind of asynchronous processing to your system. Maybe you need to upload data from customer S3 buckets, or you need to send emails or notifications, or some other thing you need to "process offline".

You could add this to your monolith, by adding some sort of background pollers that read an SQS queue, or a table in your database, then do something.

But that's actually pretty complicated, because now you have to worry about how much capacity to allocate to processing your service API and how much capacity to allocate to your pollers, and you have scale them all up at the same time. If you need more polling, you need more api servers. It become a giant pain really quickly.

It's much simpler to just separate them then it is to try to figure out how to jam them together.

Even better though, is to not write a queue poller at all. You should just write a Lambada and point it at your queue.

This is particularly true if you are me, because I wrote the Lambda Queue Poller, it works great, and I have no real reason to want to write it a second time. And I don't even have to maintain it anymore because I haven't worked at AWS since 2016. You should do this to, because my poller is pretty good, and you don't need to write one, and some other schmuck is on the hook for on-call.

Also you don't really need to think about how to scale at all, because Lambda will do it for you.

Sure, at some point, using Lambda will be less cost effective than standing up your own infra, but you can worry about that much, much, much later. And chances are there will be other growth opportunities that are much more lucrative than optimizing your computer bill.

There are other reasons why it might be simpler to split things. Putting your control plane and your data plane together just seems like a head ache waiting to happen.

If you have things that happen every now and then ("CreateUser", "CreateAccount", etc) and things that happen all the time ("CaptureCustomerClick", or "UpdateDoorDashDriverLocation", etc) you probably want to separate those. Trying to keep them together will just end up causing your pain.

I do agree, however, that having a "Users" service and an "AccountService" and a "FooService" and "BarService" or whatever kind of domain driven nonsense you can think of is a bad idea.

Those things are likely to cause pain and high change correlations, and lead to a distributed monolith.

I think the advice shouldn't be "Use a Monolith", but instead should be "Be Scrappy". You shouldn't create services without good reason (and "domain driven design" is not a good reason). But you also shouldn't "jam things together into a monolith" when there's a good reason not to. N sets of crud objects that are highly related to each other and change in correlated ways don't belong in different services. But things that work fundamentally differently (a queue poller, a control-plane crud system, the graph layer for grocery delivery, an llm, a relational database) should be in different services.

This should also be coupled with "don't deploy stuff you don't need". Managing your own database is waaaaaaay more work that just using Dynamo DB or DSQL or Big Table or whatever....

So, "don't use domain driven design" and "don't create services you don't need" is great advice. But "create a monolith" is not really the right advice.

Re: Microservices are a tax your startup probably can't afford

#196

Earlier quoted context omitted.

> If it is possible for that other team to merge a broken build, you are doing it wrong. This assertion is unrealistic and fails to address the problem. The fact that builds can and do break is a very mundane fact of life. There are whole job classes dedicated to mitigate the problems caused by broken builds, and here you are accusing others of doing things wrong. You cannot hide this away by trying to shame software…

I haven't seen a broken build in at least nine years, not since I left the company with a merge process built out of bash scripts that took three hours and required manual hand-holding. I am genuinely curious what situations you are seeing where builds are making it through CI and then don't compile. It isn't always worth investing in quality, but when it is it is entirely possible to write essentially bug-free softw…

You are absolutely right.

Of course, if people wrote bug-free code, then there would be no bug !

Bug-free code in the actual code, or bug-free code in the test code, this is the same story.

If you write stuff and never have any bug, then either:

  - you are lying
  - you do not write much
  - you only write really simple things
  - you are Jesus, came back from heaven to shine his light on us, poor souls
The more complicated, intricate stuff you have, the more bugs you'll get (and only time will allow you to fix that).

Tests are great do define how you think it should work, and to ensure it keeps doing that way. Take the time to think about the third point on the bullet list above.

Re: Microservices are a tax your startup probably can't afford

#197

Earlier quoted context omitted.

> but a monolith with more than 50 developers working on it (no matter how you split your teams) isn't great either. Why can the game industry etc somehow manage this fine, but the only place where it's actually possible to adapt this kind of artificial separation over the network, it's somehow impossible not do it beyond an even lower number of devs than for a large game? Suggests confirmation bias to me. The main p…

Consider that game programmers are generally more skilled than enterprise devs due to tougher domain constraints and role scarcity.

But if that's true, it seems like a bad idea to introduce that chain reaction of complexity to less skilled devs.

Re: Microservices are a tax your startup probably can't afford

#198
post #32

Microservices are the software architecture analog to Conway's Law. You can't help but introduce some sort of significant architecture boundary at the boundary between teams, and while that doesn't have to be "microservices" that's certainly a very attractive option. But on the flip side, introducing those heavier-weight boundaries on to yourself, internal to a team, can be very counterproductive. I can't prove this…

Conway's law is about communication, not team boundaries. There is no requirement that we introduce a significant architectural boundary at the boundary between teams: companies choose to do so to avoid having cross-team communication. The only way for significant architectural boundaries at team boundaries to not result in incredibly painful software, especially for a growing team, is to let the software organize th…

"Conway's law is about communication, not team boundaries."

I'm a spirit of the law sort of person, not the letter of the law. I don't care how you draw your internal organizational diagram; communication barriers are your team barriers.

It's for management to read the flow over time and keep the de jure boundaries somewhat sync'd with the de facto boundaries, but in the meantime the de facto ones are what will get written into your software.

Re: Microservices are a tax your startup probably can't afford

#199
I don't know what the "right" answer is, but I worked at a company that built a fairly unwieldy monolith that was dragging everyone down as it matured into a mid-sized company. And, once you're successfully used at scale it becomes much more difficult to make architectural changes. Is there a middle ground? Is there a way to build a monolith while making it easier to factor apart services earlier rather than later? I don't know, and I don't think the article addresses that either.

The article does mention "invest in modularity", but to be honest, if you're in frantic startup mode dumping code into a monolith, you're probably not caring about modularity either.

Lastly, I would imagine it's easier to start with microservices, or multiple mid-sized services if you're relying on advanced cloud infra like AWS, but that has its own costs and downsides.

Re: Microservices are a tax your startup probably can't afford

#200

Earlier quoted context omitted.

Even if it builds successfully, I've never worked anywhere where automated tests prevented 100% of problems and I doubt I ever will. For most systems of sufficient complexity you are testing in prod, even if you did a lot of testing before prod as well.

That's even more true for microservices, though, since I have yet to see a microservice architecture that automatically runs end to end tests before deploying. The post I was replying to said "your build will still break": that's what I was taking issue with. In this day and age there is no reason our trunk build should ever be broken.

Yes, I suspect some of the back and forth is the fuzziness of the term "broken build", whether that means the code literally doesn't compile or it does but the code does the wrong thing.

I agree that you can prevent merges that cause compilation errors in nearly all cases!

Post reply on HN