Mini-guide to scaling your app:<p>Step 1. Measure, measure, measure: response time, page load time, query time<p>Step 2. Identify bottlenecks: Why isn't your page load snappy? Too much JS? Round-trip to DB is killing you? Your mongrels are overloaded?<p>Tip: Use YSlow for frontend measurements and take most of its advice<p>Step 3. Fix bottlenecks: Lots of techniques to fix faster frontend performance, start with YSlow above. Architectural and backend issues can be solved with a combination of hardware (load balancers, more web boxes, more db boxes) and software (better caching strategies, evolve your DB architecture, break up your application into smaller micro-apps that scale independently)<p>Step 4: Go to step 1 and keep at it.<p>I'd have to say that if you're not doing Step 1, you're going to fail now, or eventually. As one of my first mentors taught me:<p>"You cannot improve, what you don't measure"
After the easy stuff: move your database to its own server, add a load balancer in front of additional web servers, implement memcached, start splicing your database to multiple servers, continue to add web servers, serve your static files from a cdn
Check out:<p><a href="http://highscalability.com/" rel="nofollow">http://highscalability.com/</a><p>About 20-30% of stuff posted there is worth reading, which is pretty good =)
Do the easy stuff first:
1. Enable caching & get the HTTP-headers with e-tags and stuff.
2. Get DB schema with proper indexes & tune database settings.
3. Buy better hardware where there are bottlenecks
4. Fix the software ;)
Measure and optimize. I write pretty careless code, as far as optimization goes, so first round is actually adding indexes to the database. I know what you want to say, I should do this from the start, right? But then I'd end up with a bunch of useless indexes who eat up update times and space.<p>Second step is usually cache - local, in-application cache. It's pretty much auto-pilot now, writing a cache function.<p>Cache helps, but not as much as you'd think. When it gets serious though it's still useful because its shape makes it easy to go to step three: mix the cache with a bit of refactoring. This can mean simply pre-fetching: there is a huge difference from doing 20 "select * from order_items where id=xxx" and just one "select * from order_items where order=yyy". And with the cache in place it usually means only a few extra lines of code. (This example is for building reports, not for displaying orders. I'm not that of an idiot to get each order_item separately).<p>If things get heavy refactoring can go as far as breaking the abstractions in place. Last month I squeezed an extra second by sending to the browser a big table in batches, while I was computing it. Not something I want to do every day, but occasionally it's fun.<p>This is also the step when I usually realize I made a stupid mistake along the way which caused the delay.<p>The only problem I met which was mostly impervious to this was a design decision. In one app I decided (as I usually do) to compute stuff like balances and debts on-the-fly. It usually (well, always) is a good idea, because any intermediary result is a source for bugs. But this particular app grew rather unexpectedly large, with the result that computing an overall balance takes 3-10 seconds. It's not a huge problem for the client, but my pride suffers. I'm still looking into this one - I think some refactoring may make it ok.
Check out this presentation, it includes almost everything you need to know about scaling: <a href="http://www.coderholic.com/the-ultimate-scalability-presentation/" rel="nofollow">http://www.coderholic.com/the-ultimate-scalability-presentat...</a>
Design it well in the first place!<p>Here's something I recently wrote about speed and web apps: <a href="http://bens.me.uk/2009/fast-web-applications" rel="nofollow">http://bens.me.uk/2009/fast-web-applications</a>
We scale Streamfile.com with Erlang. Both front & back-end.<p>Check out:<p><a href="http://www.erlang-web.org/" rel="nofollow">http://www.erlang-web.org/</a>
Scaling on the cheap:<p>1. Host all your static files (images,css,js) on Google App Engine<p>2. Avoid hitting your database. Cache everything possible.
What are the effective strategies to use when the bottleneck is disk I/O? We have memcached to cache data that is frequently accessed. However our usage pattern is such that repeated access of data in a short span of time is rare.
Generally we stick with caching, when that starts to give diminishing returns we add a web server. Database stuff is quite a bit harder, of course, we're been fortunate there so far :)
horizontally (keep adding cache and load balancers/proxies).
all you have to do is keep making more profits and keep buying more hardware into infinity.<p>sure, one day you'll have to build a nuclear reactor and tap a dam to provide all the power and cooling for the datacenter space, but it's easier than a redesign.