Background
Assume that we are working on an enterprise application where the customer base is too large. We need a website that is "always on", "always responsive" and "super fast". We might think that this is an easy task and we do not need to worry about these non-functional requirements when we think of the architecture. Thinking so is a wrong conception and we will see why.
A general thought is, at the start of project we always (or usually) ignore these non-functional requirements and then on the day of UAT/PROD we spend nights fighting to solve issues injected due to these neglected requirements. A common issue is "the client asks to deploy the website under load-balancing after UAT" and now your application starts misbehaving. We will see reasons and solutions soon, before that we should understand what load-balancing means, in the next section.
Load-balancing
As the name suggests, load balancing should be a technique that can handle a large load. Load in the sense of a number of concurrent users of the website. More details can be read here. But how is this different than the traditional deployment? In traditional deployment we would be deploying on a single server box. It can be a high-end physical server (that is very costly) or we can purchase a virtual server. These days, we prefer virtual servers since these are easy to acquire and scale up. Scale up here means adding additional resources (RAM/HDD and so on).
In load-balancing, we would be deploying onto multiple servers that are behind a "load-balancer". So if you have 4 servers in a load-balanced environment, ideally you will deploy your application on 4 machines. This way, the "load-balancer" will ensure that you utilize all of the servers equally and gain tremendous performance over the single machine traditional deployment environments. So how does this affect our thought when deciding the architecture of our project? We will answer this in the next section.
Architectural considerations
Before we jump to the decisions, we need to make considerations during the design of the website. For this, we will first look at the issue that develops due to load-balancing deployment environments. Since there are multiple servers in the picture now, how will we synchronize the sessions across them if we need to use it? Simple enough, we can save a session to SQL Server / any other out-proc medium and we are done. No, not at all. Just making a session out proc won't help you. When we say we will save it an out proc, this means that you are placing restrictions on what can be placed upon the session. The session now needs to be transferred over the wire (to save to some DB server) that mandates that everything that needs to be saved inside a session must be serializable. Otherwise get ready for weird issues.
So this way, in case of large applications, if we do not think about this, we cannot proceed. Hence a thought is to always require during the architecture to be prepared for the website. As explained for sessions, we might also need to have a similar line of thought for the Cache as well.
So the bottom line is, the developer/person responsible for jotting down non-functional requirements should be knowledgeable enough to understand such scenarios and the knowledge should be transferred to the development team for final implementation. The development and QA team should actually simulate load balanced environment days before the planned deployments on UAT. Load testing is also a good place where the development team can see whether they would be able to get the required performance SLA.