When possible, horizontal is better because it has more scope to scale; vertical is limited by the amount of resources you can pack into a single instance. But some applications cannot be scaled well horizontally, and for those applications vertical is the better choice.
Can it go horizontally?
Many applications are not designed to go horizontally. An application that uses local files, for example, cannot share them with an instance on another system. If files are made available to another system using, say, NFS, the file locking available may not be sufficient for resource contention and coordination.
Designing an application to be horizontal imposes complexity. And even an application that was defined to go horizontally - say, a web tier with a number of machines working with a backend database server - may have limits. It may be that each web frontend consumes 1/10th of database server capacity - so what happens when you amp it up to 11? The database becomes a bottleneck. You go back to step 1 and repeat the horizontal architecture work you did to apply the database server as well, and the system again mushrooms in complexity.
Horizontal systems are hard. Vertical systems are the default. Therefore, often vertical scaling is the only thing you can throw in front of a DDoS.
Wins you get with horizontal scaling
If you can go horizontally, however, there are a number of wins that make it superior.
- Cost - If you need 10, two 5x boxes are a little more expensive than one 10x box. But if you need 20, four 5x boxes are probably cheaper than one 20x box.
- Capability - Vertical scaling has limits; there may be no such thing as a 50x box, but ten 5x boxes is achievable. Memory only comes in sticks so big, and you can only plug so many of them into a motherboard...
- Path - If you have a vertical solution, you're generally limited to one datacenter and at most a small handful of networks coming in. If you have a horizontal solution, and can spread across multiple sites, then you greatly increase the carrier redundancy available to you.
- Robustness - by definition, if you designed your app to be horizontal, you probably designed it to cope with one or more component nodes becoming unavailable. Once you've got that, then the loss of subsets of your horizontally spread architecture are survivable.