Client-server applications have a number of advantages over centralised programs. Not only is the processing load on the central server lightened significantly, by moving some of it to the client machines, but the user interface of a program can generally be made richer in a desktop application than is possible with a centralised one.

The downside of client-server operation is, of course, that the load on the network between the client and the server is increased. Whereas with a centralised application all that went up and down the wires was details of the users' keystrokes and the resulting (often text-based) screen output, the data moving between the desktop end of the client-server application and the central machine is potentially much greater. We therefore need to be careful how our client-server applications are designed and built.

Where do we place the program logic?
The key to finding an effective compromise between central processing and distributed processing is to make a rational decision of where the operating logic of each application should lie. The trick is to place any program code close enough to the central system to keep network traffic down but to keep it sufficiently far away as to reduce the load on the central system. The usual average-case approach is to implement a program as a three-tier concept.

In a three-tier package, you have three levels (tiers) of processing. At the bottom (and on, or close to the central system) is the data access layer, where the interaction with the business's data happens. At the top is the user interaction layer - the presentation of the data to the user via whatever text- or graphics-based user interface (UI) technology we wish to use. In the middle lies the business logic - the program code that manipulates the underlying data based on the instructions the user gives via the UI.

Some examples
In some cases, all three tiers live in the same place (which often means that they're not even built as discrete tiers). The obvious example is a simple desktop application, which incorporates the user interface, the operating logic, and the storage of data, user preferences and the like, in files on the local hard disk. It's when the applications become distributed that the decision about where to put the various bits of logic becomes important.

Let's say, for instance, that we have a Windows-based CRM application that uses a central SQL Server database. The latter is clearly the bottom, data storage tier of the application and the PC application is the top, presentation tier. We have some options as to where the middle tier lives.

First, we could put the business logic entirely on the client, which means that each client works with an entire copy of the company data. This gives the lightest loading at the server but means that each client is transferring wads of data and, with large datasets, will struggle to process the data efficiently.

Second, we could put the business logic entirely at the server. This would require much less data transfer between the server and the client, as the raw company data would remain at the server. But the majority of the data processing would remain on the server and we'd have minimal benefit when compared to an entirely centralised system (but with the downside of having a bunch of clients to support with updates and bugfixes).

We clearly need to put the business logic somewhere in the middle, then. In its simplest form, this could be a server that sits between the server and the clients and provides the mapping between what the client machines ask for and the raw company data: Click here to see Figure 1 Note, the fatter the arrow, the greater the data transfer.

The problem with such a regimented approach is that although the traffic flows between the application server and the clients are relatively sparse, there is a vast amount of data being shipped between the application server and the database server. The bonus is, of course, that the latter has relatively little work to do. It's the application box that does the work but we may still come up against bottlenecks. An alternative approach, then, is to retain the three tier model but not to restrict ourselves to individual systems when placing the tiers: Click here to see Figure 2 In figure 2, the business logic still sits between the data layer and the presentation layer but extends out of the application server and into the database server. In our example of a CRM application, this would probably be achieved by placing logic in stored procedures inside the database, and calling these stored procedures from the application server. The thinner arrow between the database and application servers in figures denotes that the inter-server transfers are much reduced when compared to figure 1 - though of course, there will be a greater processing load on the database, in this instance.

This is precisely the point - in an ideal system, you will be making the most of the power of all the components. Just as you don't want to max out the CPU on a single server, there's little point going to the other extreme and leaving a high-powered central system just ticking over while the application server and the network links suffer. A sensibly designed client-server implementation will be built in a structured manner (perhaps using the three-tiered approach we've considered here, perhaps with more layers if the business problem is more complex) but will spread the load sensibly across the available equipment and links.