Separation of concerns vs Physical Segregation

aka Do I really need an App server

If you've ever planned out an application I'm sure you've heard the term "n-tier".  The idea is to take the logical capabilities required in a system (i.e. presentation, business logic and data management) and distribute them physically across a number of servers.The classic Microsoft diagram looks like this:There are a couple of guidances from MS about how to deploy these logical tiers, but they fundamentally resolve into distributed and non-distributed models:

Non-distributed
Distributed
The argument put forward by the experts is:> Because all of your layers share resources, one layer can negatively affect all of the other layers when it is under heavy utilization. In addition, the servers must be generically configured and designed around the strictest of operational requirements, and must support the peak usage of the largest consumers of system resources. The use of a single tier reduces your overall scalability and maintainability because all the layers share the same physical hardware. http://msdn.microsoft.com/en-us/library/ee658120.aspxAnd I can see the logic here: if image processing or data crunching in your lower tiers chews up too much RAM on a non-distributed deployment, even the basic static web rendering will be impacted for all clients connected to that node. Other arguments are made for security (e.g. You can put a web server in the dmz and keep your business logic secure in an inner zone), scalability (e.g. You can scale out just the tier which sees the heaviest load) and re-usability (e.g. An app server allows the business logic to be used by both the web client and an API).  All very valid point, but I wonder how valid they still are.

The Web as a rich clientIt seems to me that the there are a couple of assumptions that inform this architecture that are less and less true:Page rendering happens on the server, synchronously;Complex, data centric, business logic is norm for the business tierScaling horizontally is difficult and costlyToday's web applications are typically jQuery rich, asynchronous, likely REST based and overall very chatty between client and web server.  But lets take each assumption on its own.Page rendering on the server, synchronouslyIn a modern .Net MVC application (or RoR application, or pick your flavour of MVC/REST), while its still possible to render a page synchronously, user expectations for responsiveness and interactivity have pushed more and more of the rendering to templates on the client.  In some cases, that's just an AJAX call to the server to render a partial view that is appended to the DOM, but the key is that those additional calls for server rendering are asynchronous and to a large degree stateless.  This means that the load on the entire stack has been segmented into 10s if not 100s of specific, tiny rendering requests rather than a single all encompassing page.  Each of those requests could be distributed across a farm and would take a fraction of the processing, or likely more importantly, the memory of trying to render the page all at once.Complex, data centric, business logicAs mentioned above, many of the web applications of the past decade were over-inflated, fragile, state-full web based wizards for badly defined business workflows.  The technology framed the business process and processing and memory required were badly impacted.  And heaven forbid you click the back button.  But a  move to RESTful services and CQRS has pushed a lot of web application design to discreet, intent based commands to minimize the impact on the overall infrastructure.  Sure, we'll always have multi-stage transactions and sagas (or workflows) to manage.  But one could argue that that is the exception in most business processes, not the norm.  Scaling horizontallyScaling horizontally is the name for adding more servers to your farm.  Whether that's more web servers, more app servers or adding some other specialized resource, the goal of horizontal scaling is to reduce the average individual impact to a node in the infrastructure.  In the past that meant buying, configuring and installing another piece of hardware and was relatively high cost and risk.  Today, though, in the world of the cloud and the dynamic image provisioning of tools like VMWare and AWS, turning up horizontal scaling is a matter of a setting in a web portal.  On Microsoft's new Azure dashboard, its a pretty slider and in many cases, regardless of the platform, it can be done automatically based on metrics you set.  Having deployed in a modern infrastructure, a properly encapsulated application can be scaled almost effortlessly.To App Server, or not to App ServerSo, in the end, is there an answer?  I guess it all comes down to religion.  I'm a firm believer that in a properly designed web application, with a load balancer in the DMZ and the web servers in a protected zone, that a non-distributed MVC asynchronous application deployed over a number of load balanced nodes (with affinity) will out perform an n-tier application with no degradation in security.  Imagine a firewall to the left of the web servers, with a load balancer facing the clientYou'll likely have to do something different for an API (i.e. no or less reuse) but you probably should anyway as the API will have different stakeholders and requirements.That said, this kind of progression is what leads us to a fully Service Oriented architecture where the concept of an "Application" gets so thin that introducing the overhead of a separate Application server is almost heresey.  Next time.