From Ember to Rails

Spoiler: this is not a sad story.

In the origin

The team I work with at Heroku is called “Support Engineering”.
While you can see me spend around half of my days investigating and answering support tickets, I spend the other half improving our support tools.

For over a year now, we have been running our own support platform. The reasons behind this choice are another story.

On may 13h 2014, I pushed the first commit to the original agent interface for our support platform.
If help.heroku.com is the visible face of the iceberg, that agent interface is (part of) the hidden face.
It allows herokai and add-on providers to see support tickets, answer them, apply macros, and much more.
This app is built with ember, and started as an ember-rails app which then evolved into something custom-made with node (not the best days) and to ember-cli (much better).

On october 9th 2015, we retired this app and are now using rails.

Note that we aren’t the “typical rails app”. This app isn’t using a database, but communicating only with APIs.
Some requests are made using ajax calls, but most of them are happening server-side.

Are you crazy? Why the f* did you do this?

This was not an easy decision to take. We’ve been talking about it since january. And even then, we had spent 4 months trying to resolve our main problem.
Yes, in the end, we had only one big problem with Ember. Except for that one, we were quite happy with it.

The problem was bus factor. We’re a team of 3 people, all of us working mostly on server-side apps with ruby.
Don’t get me wrong. All my teammates are very smart people.

Coding a javascript app which evolves and where everything needs to be asynchronous is just not the same thing as running a server-side app.

After several pair-programming sessions, multiple hours spent in online training, the situation was not improving and I was still the only one who could contribute to this app.

But rails, why?

The answer can be summarized in two words here: asset pipeline.
We don’t want to be maintaining a javascript (yes we do still have a bit of js) precompilation stack.

Except for that, our platform hasn’t changed at all. Our app is still consuming the very same API. It’s just being called server-side instead of client-side.

There’s a lot of other JS frameworks. Why didn’t you use any?

We kind of did. Our help app is using React for many components.

The problem with react is the lack of conventions. It’s a very good tool for building small components.
But keeping a clean codebase made of dozens of components can quickly become a mess. That’s what we’re starting to see in that help app, and we don’t want it in a bigger way in the agent interface.

Any gotchas?

Knowledge is king

We know a lot more about our needs today than we did a year ago, which explains why it took us just a month to rewrite it.

I still like Ember very much, and our dashboard is built with it and not moving away in the foreseable future.
At some point though, it’s not about the technology. It’s about your customers (in our case, herokais), keeping them happy and being able to iterate quickly and improve with your growing needs.
If I had to go back a year behind, I would still do the same thing. We learned a ton of things on our product by using ember and migrating away from it.

Unavailability and latency

In a quite funny way, moving to rails has slightly improved our performance.
A full page load, including ajax calls and dom rendering took around 7k ms on the ember app. The same page is rendered in 2.4k ms with rails (and a bit if caching in the API calls).

The one person who’s seen the biggest change here is Steven, who does support from the middle of nothing in Australia.
His performance was quite bad, as data had to cross the pacific for each ajax requests. With most requests being made server-side, his latency has been vastly improved.

Finally, if you’re thinking of doing the same thing, never forget that your API can go down (and if it can, it will inevitably do sooner or later).
Don’t forget to build it in a resilient way, with timeouts at all levels.

A client-side request to an external server which times out doesn’t matter much. The same request made server-side can bring your entire app down. Never underestimate them.

In the end

As I spoiled at the beginning, this is not a sad story. Our customers were very happy with the ember interface.
Building the new one allowed us to make a few different UX choices allowing us to resolve several blockers on planned evolutions.

The message of this article is not that Ember is bad. Ember is a very good framework, which can work for a lot of use cases and you should definitely consider it for your app.
What matters in the end is not the technology we use though. It’s how we can resolve our customer’s problems and evolve as those problems evolve too.