One of the interesting questions that plagues the world of IT in application provisioning is "Should I scale or should I grow?" in the context of how we bring application environments up to meet the demand. When given the choice of scale up or scale out, quite often the operations and development teams are left at odds about which is the right way to go.
Perhaps there isn't a single right way. The real challenge that comes when asking this question is around which development practices you can make use of for each application.
Up, Up, and Away: Scaling Vertically
This is the more traditional approach to scaling an application environment. It's been around since physical servers were the platform of choice really, but it was obviously much more difficult to make use of when there were physical changes needed.
Scaling up means adding more memory and CPU resources available to the application. This can be done as mentioned in a physical server, but required an outage to deploy new hardware. Along came the capability of hot-add hardware, but just as trust was growing adding memory to a system while it was powered on, the dawn of virtualization was upon us.
Scaling vertically in a virtualization environment means adding more virtual CPU or virtual memory to the VM which ultimately means giving more usable resources for the application. This may or may not attend to an issue around performance, but it was and still is the only way to add resources if an application is the traditional monolithic architecture.
Outward Bound: Scaling Horizontally
The more desired scaling approach for applications is horizontally. This implies that we use the N-tier, or multi-tier approach by separating the various infrastructure components. Front-end web servers are put in place, with middle tier message queuing such as RabbitMQ. Then the underlying database components are created, preferably on a horizontally scalable database platform like MariaDB, or even on a DBaaS (Database-as-a-Service) offering.
This means that each of our components can be grown as needed, and they are all loosely coupled. Clustering and load balancing tools are placed between each of the tiers to allow for abstraction of each of the individual components. Even in the case of a small initial deployment, the flexibility of growth is built-in to make sure that scaling outward will be possible as needed.
Which One to Choose?
Many times you will see the reference to monolithic and legacy applications as being viable candidates for scaling upwards. This is because the development tools and techniques that were used for some of those legacy applications may have only been able to add more local resources. Message queuing and middleware applications were not always employed and many apps were built with local web and database components. Obviously, it is difficult to scale horizontally when the application is architected this way.
Even where tools and methods became more versatile, and N-tier development was possible, it didn't necessarily make sense to design every application to be multi-tier with loosely coupled components. If you were building a small time tracking application, or some smaller scaled tool, building to suit the needs at the time may have been all that was budgeted or available. This means that scaling up becomes the only growth option unless you refactor the application altogether.
Design for Tomorrow, not Today
If given the option, it should always be to design for potential growth and not just to tackle current minimum requirements. While MVP (Minimum Viable Product) was coined as a lean startup technique, it was meant to be iterative. Design for tomorrow, and when you can, think about scale. Remember that if everything goes well that you may see that application get some serious uptake.
Image source: http://dc.wikia.com/wiki/Superman:_Up,_Up_and_Away! (Featured Image)