Big Architecture Up Front - A Case of Premature Scalaculation?
An interesting discussion recently surfaced in the blogosphere as to how much time should be spent up front designing for scalability. Dharmesh Shah, of OnStartUps, initiated the conversation by writing about the dangers of "Premature Scalaculation":
In startups, the technical founder often wears his skills as an architect of scalable systems as a badge of honor. Lots of time and money is spent making sure that should the company ever hit the spectacular success that everyone on the team knows is inevitable, the system (software and infrastructure) will be able to handle it. Quite often, this is misguided.
The premise of the article is that valuable resources should be directed towards more pressing business needs rather than plumbing:
These resources should be spent trying to figure out what is going to work and not on intricate software designs, code optimization and infrastructure upgrades.
Is it still valid to assume it is more expensive to design a scalable system? (Alternatively: Does it cost less to design a system that doesn't scale?) Todd Hoff doesn't think so:
If I ever believed this I certainly don't believe it anymore. The world has changed, even since 2005.
Thanks to many books and papers on how to scale the knowledge of scaling isn't the scarce precious resource it once was. It's no longer knowledge tightly held by a cabal of experts until Nicolas Cage flies in and pries it out of their grasping dessicated fingers. Now any journeyman computerista can do a reasonable job at designing a scalable system.
Kevin Johnson took issue with the notion that scalability is an "optimization problem", and identified other factors to consider in the "up front costs that may bite you later" category:
It's a fundamental mistake to frame scalability as an optimization problem. Scalability fall into the non-functional requirements bucket. It keeps company with a shady cast of characters - security, maintainability, usability, and all the other *ilities. The primary challenge with non-functional requirements is they tend to pose the risk of significant rework if not taken into account early in the architectural and design phases of a projects.
To be fair, Sinclair Schuller points out additional rationale that Dharmesh provides in a follow up comment:
One point I didn't make in the article, but probably should have: When making tradeoffs regarding scalability, you are at some level incurring technology debt. Debt is not always a bad thing -- it can often help you grow. The key is to make sure that the "interest rate" on the debt does not outweigh the benefit of the tradeoff. So, if making a scalability tradeoff will likely cause you to rewrite the entire system, it's probably not worth it. But, if it's simply a matter of "Pay X now or 1.2X later", it might be better in some cases to just pay 1.2 X later".
Jamie Flournoy makes an interesting point in "Capacity vs. Scalability" suggesting that there is an inflection point at which it makes sense to focus on scalability based on capacity requirements:
Scalability is a very distinct concept from capacity. Scalability is not a true/false property of a system; there are degrees of scalability, which can be represented in a 2D graph of # of simultaneous requests that you can service with an acceptable response time (X axis), plotted against the resources required to service those requests (on the Y axis). The function f in the y=f(x) equation that is behind that graph is how scalable your application is.
If it’s a straight line, that’s quite good: “linear scalability”. More requests cost the same amount per request as the ones you’re getting now. Double your customers, double your net profits.
If it curves down away from a straight line, that’s even better than linear scalability: you’ve attained an economy of scale, so twice as many requests costs less than twice as much as the amount you’re paying now.
If it curves up away from a straight line, that’s bad, because more load means a greater cost per request. Each new customer makes you less money than the last one. Eventually you will grow to a point where you lose money and your business fails.
The more interesting questions, though, are how much it costs you to add capacity, and whether there’s a certain number of requests above which you start to make or lose money.
Software design and architecture at project inception often involves juggling numerous tradeoffs at deep business and technical levels. Factors such as platform, database, language and tool choices come into play. The challenge for architects getting any project off the ground is to use their experience and intuition to help guide the decision making process, appropriate to their circumstances. Yes, "skills as an architect of scalable systems" are "a badge of honor", but that undermines the role of the architect in focusing on "customer/business value as well as technical details", as Ted Neward says.
Can architects be trusted to make technical decisions that significantly affect the business? What guidelines do you use in figuring out how much time to spend on design/architecture up front?
There's no such thing as "Premature Scalaculation"
Design first, scale with technology later
By first employing the Separation of Concerns principle, we keep the specific technology used to scale out of our core logic. Next, (or possibly even first) we employ, up front, all the patterns of scalable design.
This prevents costly rewrites, defers costly technology choices, and let's a project "bootstrap" the scalability aspects of a system.
I've got a full write-up on my blog here:
Scalability - you wish you're gonna need it
Think about it upfront
Also, testing scalability is a good idea. If you're deploying one node to start, have a lab going from day one with 2+ nodes.
Since scalability is essentially the incremental cost of performing one more transaction above some threshhold, you can reframe the discussion to non-technical people in these terms: "If it costs us 1 unit/customer to serve our first customer, it will cost us 5 units/customer to serve our 100th and 25 units/customer to serve our 1000th - are we comfortable with this tradeoff?"
More than architecture
Re: More than architecture
I guess my question to you, Oleg, would be:
How much development effort would be required to take the same system and make a single server support 10X as many concurrent users? If we're talking a man-month or so, that would be acceptable to me, as a business owner.
I guess what I'm saying is that the cost/turnaround-time to improve the scalability is a very important business-oriented measure. That was what was at the root of my previous comment; the way development resources are invested between functionality and *-ilities.
Does that make sense?
Re: More than architecture
A man-month to get 10X improvement is only possible if the current app has glaring performance bottlenecks which are fairly easy to solve. In a large, complex application performance loss is spread throughout. Fixing it is more of a process than a dedicated one-time undertaking. In these cases, putting an estimate figure on this effort is, in my opinion, a wild guess.
To make it complex, not to make it complex.
As any other quality attribute, the first mistake is to leave it as "later task" once the functional requirements solution is designed. That is a bad habit quite common.
As mentioned, scalability is not a binary thing. Like security, you must determine the approximate value (level) of scalability needed for business, which will not require much trade off. Then you focus on building it.
You cannot make all that simple and not include scalability analysis. You cannot either, create a very complex system that scales at infinitum. Probably the best approach is to aim a little bit higher than what the business analysis tells you its needed, and then, while developing, adjusting up or down. Remember architecture is not documentation written in stone, it is a living idea that evolves during creation.