2 ms·
I don't think that there are any good answers to scaling, since it's a complex topic and finding a balance is difficult, with the situations at the both ends of
by KronisLV 4y ago
I don't think that there are any good answers to scaling, since it's a complex topic and finding a balance is difficult, with the situations at the both ends of the spectrum being rather bad - either crippling the future performance by unscalable architecture decisions (which may or may not ever be relevant), or not getting anything done due to overengineering ahead of time (premature optimization).
That said, personally I think that there are a few things that take very little effort and can help you avoid a "singleton" application, which cannot be reasonably run on more than one instance and thus presents not only horizontal scalability risks, but also serious risks in regards to downtime since startup might be so long that your single instance going down or needing a restart will result in a prolonged downtime.
For starters, I think that the 12 factor app principles are pretty good: https://12factor.net/ https://12factor.net/
But for the most part, you just want to lean towards a "shared nothing" architecture, where you don't use local memory or local file system for persistent storage of any kind (e.g. files, session information, application caches). Sure, those are bad practices in general (e.g. all sessions being lost after an application restart if they're ever stored in memory, or even counting on a temp directory for persisting them) but I've seen them in plenty of applications in the past.
Those decisions might not be too hard to fix individually once you do care about resiliency, but if you're looking at a monolith that has been around for 5-10 years and now needs to be refactored, you're pretty much out of luck, since I've seen some with lots of tight coupling. I've actually talked about that in the past here on HN: https://news.ycombinator.com/item?id=32182047 https://news.ycombinator.com/item?id=32182047
In essence, what I'd advocate for would be doing the bare minimum towards being scalable, the things that are easy to do and also simple: like using a separate Redis instance for your caches/sessions, using S3 for storing files, always using some database for your data persistence, even if just a single instance in the beginning. Things like using feature flags in front of your scheduled processes, or enabling/disabling certain modules are underrated.
Then, if you hit a performance bottleneck 2 years down the line, you'll be able to address it relatively easily. And if you don't? You'll still have a nice architecture that should lend itself to changes well, as well as throwing out pieces and rewriting them in something else if you want (e.g. your PDF framework doesn't run on anything other than JDK8 so you need something else).
That said, if you're working on small projects that aren't meant for a business and don't exactly have customers (that expect some sort of an SLA) to worry about, then even something like SQLite being your entire persistence layer might be enough.