Since there are load of API’s around, as developers we’re able to plug them to our projects within minutes, praise “REST”. I just plugged the 5th service to the app I’m working on (no I’m not proud), it’s an all time high! I want to share some troubles I ran in to.
We had Twilio & SendGrid
This is a SAAS telephony/email marketing app. For telephony stuff we’re using Twilio and for email SendGrid as the service providers, so we had Twilio API from the beginning, users send sms through the web app, users can do sms in bulk and for larger quantities job queues and workers comes in to play. Technically we had sendgrid as well, but it was through smtp protocol, does it count?
Time goes by, we needed realtime notifications, like facebook. “Web-sockets” and “Node” was the first 2 things came to my mind since I’m not a fan of ajax long polling, I decided to go with Pusher, Pusher uses web sockets by default, but if user browser doesn’t support it, it will switch to a flash based solution. They have a good API with PHP wrappers. By the way as of now, facebook uses ajax polling
Couch DB (DBAAS)
The users mainly use the app to manage their leads/customers, and each of this lead has an activity feed, which basically records every interaction between the app and the leads. Most of these data is “not critical” and it’s not worth putting inside the main MySQL database. So I decided to try a NoSQL alternative this time, (we already had some benchmarks using this data inside main mysql db). I looked at Mongo and CouchDB, at the time mongo didn’t support full-text searching and neither CouchDB, but I stumbled upon this project on github. Luckily a company called Cloudant was already offering couchdb with lucene as a hosted service (the guy who created lucene for couchdb works @ cloudant). I moved with cloudant.
Sentry for Error Reporting
Crawling through the logs ain’t a good experience, specially on a server (at least for me), there goes I plugged another service for error reporting, “Sentry“.”Sentry notifies the developers when users experience errors in your web and mobile apps.” For PHP apps, getsentry’s library will register an exception handler to capture all the errors for reporting back, I get email notifications when errors occur plus I have a nice view of the errors (trust me you want that when checking errors :D), big time saver.
2X Performance Drop
After integrating couchdb (cloudant), the app got very slow, slow as hell. Some pages took almost 4-5 seconds to load on a decent internet connection. A ping to the cloudant servers from our server gave us around 300ms, which is very very bad for something like database communication. It turns out, our cloudant account was in singapore while the app’s server is in US. Duh! We were on a Hostgator VPS at this time, so we moved the cloudant account to USA (Chicago) thank you cloudant team! that gave us 25ms ping, not bad. Recently we moved the server from hosgator to rackspace. Turns out we’re in the same datacenter with cloudant now, yepee! and the ping dropped to 0.2ms. App is fast like hell.
Also moving from hostgator VPS to rackspace dedicated server reduced the api call times to all of our apis, before we had around 1000ms duration for some twilio calls, and around 2000-3000 secs for pusher calls (All from PHP), after moving to rackspace those numbers dropped to around 200-300. So if you’re thinking about using a VPS with lots of 3rd party services, think twice.
Background Jobs/Message Queues
The main downside of using 3rd party services is that you’re going to rely on someone else, a dependency if you will. And we can’t guarantee that it will be online when you need it and it will always respond to our requests instantly. Some part of my app had some logics which directly call twilio api on the same request of the user, while on the VPS occasionally these requests got slow as hell (so far good under the dedicated environment). The thing is it’s always better if you can abstract the 3rd party service from the end user, using job queues has enabled us to reduce the waiting time significantly throughout the whole app, since the API calls are not processed on the request it self but added to a queue which is processed by a worker later on. Sure it’s not fast, but it’s “fast” for the user.
But Why Not Locally?
Most of the services I mentioned can be implemented locally, instead of pusher I could use socket.io. Without cloudant I can roll my own couch instance on the server, there are lots of self hosted logging platforms so I can get rid of sentry. Given the time and man power it’s not always a good call to do all of these things by our selves and most importantly what I learned durin past few years was when working on start-up projects ONLY concentrate on the core features. If we hit a record in pusher, sure we can roll out own implementation later. But not now, development time is far more important than infrastructure costs, it really is. So let the server handle all the tough stuff for a while 😉
it’s not That Expensive
All of the services I mentioned doesn’t cost a dime to start off, don’t forget to test them.