$WORKat the moment. The bulk of the work involves modeling a large corpus of XML documents, extracting metadata, and providing a browse-and-edit interface for that metadata. Standard webapp. Nothing special.
Except that the work I'm focused on is on the workflow system, the part that actually reads documents, parses the metadata, and shoves it into the database.
For the front end, it makes sense that the application uses the full Rails stack: ActiveRecord, ActiveController and the like. It's just a webapp, and the CPU overhead of running the application code in Ruby doesn't matter when compared to the overhead of talking to the database and the client. The advantages of using Ruby on Rails far outweigh the meager amount of hardware it requires.
However, the backend is all about throughput, and the added overhead of running Ruby is quite noticeable. Doubly so because it uses Rails' ActiveRecord models, which spend a lot of time doing reflection on the fly. Yet none of that is really necessary; all the backend is doing is reading the filesystem, parsing XML, and stuffing it into a database. The logic for all three parts is pretty static, and there's no real benefit to using a highly dynamic runtime, especially when the cost in CPU overhead is quite noticable.
In the bad old days, problems like this had one solution: rewrite the code in C.
Today, there's an alternative: rewrite the code in Haskell.
The goal then, as now, is to remove the interpreter overhead from a long running, high throughput process. In the bad old days, that meant leaving features like polymorphism and garbage collection behind, and dealing with segfaults and memory leaks just to get something close to acceptable performance.
Today, none of those tradeoffs are necessary. Haskell can compile down to machine code, and eliminates the interpreter overhead (Thank You, Thank You, Thank You, Simon Peyton Jones!) . But it also provides garbage collection, and polymorphism. It's the best of both worlds: a high level language that compiles down to a native executable. Additionally, once a program gets past the type checker, the compiler pretty much guarantees that segfaults go away. Time and space leaks can still occur, but the profiler can help isolate the misbehaving code with a little effort.
The last time I came across a problem like this, nearly a decade ago, there really was no way out. Rewriting a slow Perl program in C was generally seen as distasteful, tedious, error-prone, but necessary. Today, rewriting a slow Ruby program in Haskell is one of many options available, and certainly isn't that distasteful or tedious anymore. Perhaps in another decade, there will be more alternatives. Perhaps this kind of problem will just go away. Who knows.
While at Rails Edge, I mentioned this strategy to a few people, all of whom were working on Rails apps. No one disagreed that Rails can be a poor choice for backend processing, because of the high CPU overhead and low throughput. Rewriting a Ruby app in Haskell certainly seemed to make sense to everyone I talked to, at least in this one particular scenario.