CourseAdvisor Scales With Rails

Company Dan Chak
Client CourseAdvisor.com
Main features Rails
 
Excerpt

CourseAdvisor is an online directory of post-secondary schools and education programs currently serving 1.5 million users per month.

Study

What is CourseAdvisor all about? What service do you all provide?

CourseAdvisor is an online directory of post-secondary schools and education programs. We are partnered with over 700 schools offering a combined total of over 8,000 educational programs. We utilize sophisticated algorithms to match students with appropriate educational opportunities based on their interests and their student profile. We currently receive over 1.5M unique visitors each month.

Before choosing Ruby on Rails, what other languages and/or frameworks did you consider for CourseAdvisor?

We wanted a platform that had at its core a flexible language, and a framework that encouraged good design principles and application scalability. We were also looking for a stack that was well supported and had a good community behind it.

Our V1 site was written in PHP/Drupal on MySQL, and we wanted to get away from that. It’s too easy to write bad code in PHP that is hard to refactor, and which won’t scale as a project gets big. So PHP was a non-starter. We also didn’t spend very much time considering various Java solutions; we wanted to be nimble, have a quick release cycle, and we didn’t want a language where it takes a lot of code to say very little.

So our three contenders were Django (a python framework), CherryPy (another python framework), and Ruby on Rails.

What are the main reasons that you chose Ruby on Rails? What benefits are you getting using Ruby on Rails?

It was a pretty tough choice to choose Ruby on Rails in late 2005. Python was a much better known language, and a python module existed for just about anything. Ruby seemed a little more risky, as it was virtually an unknown in the United States outside of the Rails community. However, while the python frameworks had been around for a while (relatively speaking), they didn’t seem to be igniting any fires in web development circles. On the other hand, it seemed that everyone who tried Rails became an instant diehard evangelist. We figured there was something to that, so we downloaded it and gave it a test drive ourselves. We were sold pretty quickly. Luckily in the last year and a half, other people have felt the same way, and now there is a huge Rails community contributing tons of code, plug-ins, documentation, and books.

How much traffic did the site receive when it was first launched?

When we launched our Rails site, we were replacing an existing site, so right off the bat we were receiving about 1M users per month. Of course, traffic isn’t constant and it peaks during weekdays and during waking / business hours, so we actually had to be prepared to handle quite a bit of concurrent traffic during our peak usage hours.

What rate of growth are you experiencing, and what is an average month for you in terms of visitors served?

We’re currently receiving over 1.5M unique users per month. We owe our growth to our excellent sales team that brings on new schools and programs each month, and is constantly working hard to make our directory the most complete in the industry. The job of the software team is to handle the traffic they throw at us, and so far we’ve been able to do that with Rails without massive server installations.

How do you handle the growing amount of traffic? Are you adding servers or having to refactor your code?

We serve users custom offerings based on their unique profiles, so it’s not always easy to cache query results at the application layer. Therefore, we spend a lot of time optimizing our database queries to make sure our pages render fast. Our web servers running Rails actually do very little data processing, so we replicate them more for redundancy than for scaling.

We get all our performance bang (and also experience our heaviest system load) at the database layer. One of our current technology goals is to be able to scale to 10x, which is really challenging when the database is the bottleneck. So we’re in the process of breaking up our back-end into services that are responsible for different high-level functions. These services are fully vertical Rails apps backed by their own databases, communicating with each other over XMLRPC. That’s going to allow us to spread our database load around a bit, and will also break our app up unto smaller, easier to understand pieces, each responsible for a single function.

One major theme we live by is that if you can’t serve a single page to a single user using a single server in under a second, you won’t be able to do it with two servers, either; all you’ll have is twice as many slow pages. So while we are adding servers to handle additional load, we’re also adapting our software architecture to make the best use of those servers.

What do you feel are the most important points to consider when scaling a Rails app to handle growing amounts of traffic?

Lots of people say not to worry about scalability until you really need to. That’s fine, but there are some things you can do right off the bat to make sure your site doesn’t keel over as soon as you have some real traffic.

First, ActiveRecord is great, but it’s not necessarily well suited for your user facing pages that will get a lot of traffic. Iterating over ActiveRecord objects with complex associations can literally result in hundreds of database queries just to render what appears to be a simple list on a web page. There are ways to augment ActiveRecord queries to select only the columns you want, do table joins, etc., but there’s a limit to the complexity allowed here. Also, the more complex your ActiveRecord API usage, the more your calls look like SQL anyway. The big win with ActiveRecord is that it lets you get information out of the database in a way that’s very easy to understand and also easy to change quickly. My advice is that it’s okay to be inefficient while you’re developing a feature so you can spend as little time as possible getting the feature right, but then it’s critical to go back and replace any big nested chunks of ActiveRecord calls with a single optimized query or two. That gives you the best of both worlds: rapid application development and iterative design while you’re developing your features, but also great performance when you release your features into the wild.

The other wisdom I can offer regards application size. Whenever you’re developing a new feature, ask yourself if it can be written as a plugin rather than added directly to your web app. This will help curb your application’s complexity before it gets out of control, and save you the trouble of refactoring later. When your site gains popularity and you need to hire more developers to support it, you’ll be happy to find that a trim application utilizing lots of plugins greatly reduces the learning curve for new employees. You’ll also be able to share plugins easily between your apps if you find that, like us, you need to move toward a service oriented architecture.

Are there any important points that I did not hit on that you feel are important to mention?

I think it’s important for people new to Rails to spend some time learning Ruby first. Most Rails converts are coming from the Java or PHP worlds, and it’s tempting to force a Java or PHP mentality of coding into your first Rails app. Ruby is a really fantastic and elegant language, and it’s worth learning and utilizing its finer points rather than simply re-implementing Java or PHP code with Ruby syntax. Often with Ruby, there’s a way of expressing an idea in a few succinct lines, where a page or two would have been required in Java.

Contact Info

Dan Chak – Director of Software Development – chak@courseadvisor.com


Go back to the list