Preventing Server Bottlenecks
On Sitepoint.com, someone asked about preventing bottlenecks on servers when using lots of resources. I posted some of the information that I knew off of the top of my head (I’m samanime on Sitepoint.com). I thought about it and realized that this would be an excellent topic to discuss for up-and-coming webmasters.
The Problem
The basic problem is simple: you have more users wanting more resources than your server can provide. How you go about getting around these problems is what this blog discussed. The number of changes you can make are lengthy, and they vary greatly. We’ll start out with the easy and cheap solutions first, then progress to them more expensive solutions.
Some of the consequences to these problems include:
- Users receiving server errors (404, etc) because your website is too busy to connect with them.
- Services cut off in the middle because it can’t handle your user.
- Errors about your database or server having too many connections.
- Angry users!
Free Solutions
Just to note, “free” refers to it costing no more than your basic costs.
Optimize Your Code
The simplest and cheapest method to reduce the load on your servers is to simply be sure to optimize all of your server-side code (PHP, ASP, etc.) and any client-side code that makes calls to your server (though, you should optimize it all just for good practice). There are lots of ways to optimize your code and it could warrant a whole series of articles, but here are a few of the big key optimizations:
- Minimize the number of SQL queries. Combine queries (make use of joins and such) then use a server-side language to iterate through the results (instead of making multiple queries inside of a loop and processing them one at a time).
- Minimize the number of nested for loops that you use. If possible, always look for a way you can rewrite the code to reduce the number of nestings of your loops. Remember that every time you nest a loop, you’re essentially increasing the time that portion of code takes to run exponentionally.
- Avoid persistent database connections unless there is a necessary reason for this. While it might take a tiny bit more resources to make the connection each time, it allows for more simultaneous users aren’t tying up a connection without it actively being used.
Free or Cheap Solutions
Depending on your situation and providers, these solution may be free or have a (generally low) fee.
Separate Resources to Different Sub-domains
This is a handy technique which makes use of a common browser attribute. Most internet browsers limit the amount of data you can transfer from a single domain, but not the total amount of data you can use (that is limited only by your connection and computer). In this regard, the browsers do not regard sub-domains to be the same. So, for example, I could move all of my images to load from img.htmlblox.com, all of my static pages to load from static.htmlblox.com, and all of my dynamic pages could stay on htmlblox.com.
This wouldn’t necessarily be resource saving, but it will allow users to load your pages faster. Depending on the type of website or service you provide, it could be beneficial to have them get everything quicker and cut the connection to your server, rather than having a prolonged connection.
Make Use of a Queue
A queue can be an effective bottleneck reducing tool in certain cases, especially those that require infrequent but heavy uses of resources. Websites that provide free large downloads frequently make use of this approach.
I’ll probably release a full-fledged article describing how to create a queue in detail, but the basics are fairly simple. You need two things: Something to keep track of those in the queue and something to send or receive updates and move users through the queue.
The first part is easily accomplished by just storing an entry into a database. Storing the IP address and a session variable, along with any other necessary data for your specific purpose are all you need for this. Depending how you do your update will depend what you do with this data.
The second part has many different approaches. One of the simplest would just be to have AJAX-based (Javascript) requests to the server, asking to check it’s position in the queue. In this case, the server could run a query on the database to remove any users that hadn’t communicated in a certain amount of time (meaning you would need to store this for each user, and update it for each user each time them communicate with the server). Then, it could return data to the user indicating it’s new position in the queue.
Once the user makes a request and it’s their turn, you can then send back extra data to initiate whatever it wants to do (such as sending the link to start the download).
Mildly Costly Solutions
The solutions are ones that require a bit more money, but generally not a significant amount.
Upgrade your Servers
This is in “Mildly Costly” because sometimes it only requires a couple of dollars a month (if you are among the low end). However, if you are in the high-end, this can be tens of thousands of dollars.
The solution itself is simple though; upgrade your server. If you are using the lowest shared hosting plan, move up a step. If you reach the top of that, switch from a shared hosting plan to a dedicated server. If that dedicated server isn’t enough, upgrade the server further. If you have several thousands of dollars, you can get servers that make even the most powerful personal computers look like they’re using paper and pencil to compute.
Upgrade your Connection
Like the server upgrade, this could be mildly costly or exceptionally expensive.
If your server can handle the load but you just can’t get the data out faster, you can upgrade your bandwidth. If you’re running on a shared line, get a dedicated line. If you’re on a T1, upgrade to a T3.
Costly Solutions
These solutions are generally costly. The amount of cost can vary from a few dollars a month to several hundred (or thousands) more, depending what your current setup is and what your required setup is. They are more costly because they generally involve increasing your resources at a multiplied rate (two servers, three servers, etc.)
Spread Resources Across Multiple Servers
This is along the same lines as separating resources to different sub-domains, except this time you’re separating the data across multiple physical machines. You can set each server up on a sub-domain or just have them all act like their the same machine (sub-domain is easiest).
This allows you to have one (or more) machines handle the load of the processing and transferring of the necessary data. You can separate the data by types of files (as with the sub-domain), or have every machine do the same thing and use a script to determine where it is best to send each user.
Mirror Database Across Multiple Servers
This is a similar approach to spreading resources across multiple servers, but in this case you focus on having each database on a separate server, but containing exactly the same data.
This can be a bit tricky but there is good software such as MySQL Cluster (http://www.mysql.com/products/database/cluster/) which do this for you and are quite good at it when run on appropriate hardware.
Enterprise-Grade Solutions
Oh, wait, we already covered them.
The difference between Enterprise-Grade solutions and solutions you can do yourself on a modest budget are essentially the same. The only real difference is exactly how much money you put into those. Large data centers that need ultra-high reliability (such as banks) spend hundreds of thousands of dollars setting up large groups of servers that are all linked together. However, even though it looks a lot more substantial, the basic techniques they use are the same ones you can make use of spending less than $100.
Picking the Right Solution
If you are asking which “solution” is right for you, you’re probably asking the wrong question. The correct question would be what are the right “solutions” for you because these can work together to improve your website’s performance.
The specific solutions you use will be very dependent on your specific project. It’s all about weighing your problem with the potential results from each solution.
My recommendation is to start with the simplest and cheapest and work your way up from there. When you go to upgrade your servers, upgrade in steps. There is no reason to go from a low-end shared host to a high-end dedicated server in one bound (unless you are positive you need it). Also, in general, unless you like to throw away money you shouldn’t be spending more than you are bringing in. If you are, you should take a step back and look at what improvements you can make that are cheaper, or hunt out some better monetization methods.
Also, be sure that your solution doesn’t become part of the problem. For example, implementing a queue for large file downloads is generally beneficial. However, if you decide to implement a queue for something minor, such as posting to a forum, the queue will likely use more resources than the action itself would.
This will probably be a topic I’ll revisit in the future. If you have any tips that I missed, let me know and I’ll add them in. If you aren’t sure which solutions you would use for your project, post a comment, post in our forums, or contact me and we’ll help you out!




