Scale Out NOT Scale Up
By intuition, one would beef up a server with more RAM, larger disk or more powerful CPU when there is a need to grow up. Not only this is the easiest way to accommodate larger traffic load but its also lot easier to deploy. Small and medium sites can usually get away with this solution but as you hit some serious traffic, you will realize that you can't continue doing this forever. Problems occur down the road when the data you have can't fit into the memory of a single server. There are some hard limit as well on how much you can upgrade a particular server -- both physical limit and budget limits.
Asynchronous Communication
When something needs to be saved into your database, or an API call needs to be fetch from a third-party, we usually block the execution of the app until it was fulfilled - this doesn't scale up. You have to put long running operations in the background, so that your site stays responsive and recover resources like connection handles, memory and cpu as soon as possible.
Persist chunky, not chatty Data
Lets say you are saving every click details for a particular button. Most developers execute INSERT operations to the underlying database for each actual click made by users. This will pose a bottleneck in your database and cause serious issues. Not to mention the network latency it requires specially if your database server was not in the same local network as the web server. What is more ideal is to accumulate first the data in some local storage like text file or cache. Then send the data to the database as a batch. This reduces network congestion and also makes a very efficient use of database connection.
Retry for Fault Tolerance
If someone submitted a form and the database server is currently down, what happens to the info? It was lost isn't it. Not too many users are willing to fill up again the same info specially if the alternative site is just one click away. You to make sure the data you accept from your users is placed into a temporary holding area. Then a asynchronous background process will pick it up and try to save it to the database, when the database is offline at that time, the background process should be smart enough to retry it at a later point of time, thus making it possible to still accept transactions while the database server is being revived.
Caching
You don't want to hit the database server every time you need data. Make use of Memcached or Redis to store the data you retrieved from the database, then just refresh those when something was changed into the database.
Horizontal Data Partitioning
Don't store your data into just single database server. Identify which tables you think will grow in enormous size and split it up in multiple servers. NoSQL has a built-in support for this kind of things called "sharding". MySQL have attempts to do this kind of thing but with no success. Note that Replication is entirely different from Sharding. In replication, you are putting a full copy of the entire data into another server and continuously sync the two together, while in sharding, you are splitting up your data into multiple server. So that means if you have 1 million rows table, one server has the 500k rows, while the other server have the other 500k rows. This is critical specially when you have very large amount of data and it would not fit into a single database server.
Did you find this useful?
I'm always happy to help! You can show your support and appreciation by Buying me a coffee (I love coffee!).