Similarly, you could do TDD on a high percentage of the code by using injection, then automatically rewrite the code into static methods, as Atwood was saying they needed for performance, if that’s what would help.
Code generation, etc. got a bad name over the years as people tended to use it to balloon the eventual source, like that of many autogenerated config files today, but it can be used to do almost anything.
I've consistently heard good things about Erlang/OTP.
If you have a monolith, you have less control over the service’s shape—the CPU, RAM, IO footprints. If you break it up into smaller microservices, the footprints are smaller and you have more options for how you schedule them.
There is a tradeoff here—services that are too small have high overhead. Services that are too large are inefficiently scheduled. Services that are way too large force you to spend money buying the massive machines needed to run them.
A monolith easily achieves 10x throughput of what microservices will do on the same hardware. Which is why people build monoliths, they can be extremely efficient. Microservices are usually about trading resource efficiency for organizational convenience.
> A monolith easily achieves 10x throughput of what microservices will do on the same hardware.
If we’re gonna talk about unwarranted assumptions, this one takes the cake.
I’ve seen services spun up where the resources to run them simply didn’t exist in our data centers. As monoliths, their throughput was effectively zero. The cost tradeoff was “buy bigger servers and wait until they arrive” versus “spend engineering resources and stop buying bigger servers.” Again—this is going to depend on the particulars. The better answer is not necessarily obvious.
You don't end up with lots of network calls for one use case and still have good maintainability.