From 0 to 1 Million in 6 Hours
Having an office less than a block away from a protest that’s making international headlines gave us a unique opportunity: use our technology prowess to experience live events in a new way. So what did we do? We wrote a site using Rails, WebSockets, Heroku, MongoDB, and the Twitter Streaming API. In 6 hours.
We’re using heroku to host the site, although (with a few changes) it could be hosted as a static site on S3. The nice thing about heroku is the dead-simple deployment:
git push heroku
The next step was determining the persistence engine. We chose MongoDB for the flexibility to change the amount of data we store on-the-fly. Originally, we started using the MongoHQ addon from Heroku, but we quickly outgrew its capacity. Since heroku doesn’t currently support upgrading that particular addon, we got a non-heroku MongoHQ instance featuring 2GB of storage. Sadly, we had already culled much of the data by the time that decision was made. Overall, the migration was quite easy, thanks to the MongoHQ support page.
Since we’re most familiar with Ruby on Rails, we decided to go with that. As previously mentioned, it could have instead been a static site. Sinatra would have sufficed, too.
We had some experience with using Pusher on AtaconApp, our Rails Rumble entry, and we knew the power and novelty that WebSockets provide. The quickstart at Pusher should get you started, but we had a little extra work to do server-side…
To provide a fully pushed experience—that is, no polling—we connected to the Twitter Streaming API inside a Ruby EventMachine loop. Effectively, we keep an open TCP channel to Twitter and run a block of code each time a tweet matching our search criteria is received. That block of code stores the tweet on MongoHQ and sends it off to Pusher for our visitors.
We’re handling a lot of data for an app written in a day. Friday, the day after VoiceRally was written, we sent over 1.5 million WebSocket messages. For a few moments (thanks in no small part to an eventually flagged Hacker News article), we edged up to 100 WebSocket messages per second with about 60 concurrent visitors.
And all of this was conceived and executed in 6 hours. We’ve been making tweaks here and there, but all of the functionality (including the incredibly necessary “pause” button) was done in one day.