The exception is when you're dealing with a very high transaction rate (say, doing 100K msg/sec, non-trivial processing per message, in a single process). Then the GC overhead is something to be aware of, and you'll go to extreme lengths just to remove a handful of allocations for each message. At that point, manual memory management (either via hacking up the runtime with unsafe code, allocating large arrays of structs, or using unmanaged code) is the right path. But from light reading, it seems the same is true in Java or other GC languages, so no difference for Mono there.
So the alternative is C, usually, which has its own set of tradeoffs. Rust looks far more promising, but in general, Mono's performance is just good enough that I'm more likely to keep my nice F# code and add a few boxes. Unless you're in a high-performance arena, and you'd know if you are, this likely holds true for your business.
Edit: Also, I'll note we're using Mono 2.10. So updating to 3 should get us the new GC which may make a difference, as well as allow LLVM code, which should help significantly for server apps.
All critical code is F# on Mono and CLR. Each voice-handling machine makes an HTTP request to a CLR process to get routing instructions, then the results of the call are handed off to a Mono process, which protobufs stuff into a local RabbitMQ instance, which gets shoveled into billing, analysis, etc.
Lots of "XML", as that's FreeSWITCH's preferred format (it's not real XML, but a psuedo-XML with inane encoding rules, for some reason). This is the cause of at least 20% CPU time when handling call records.
In general, scaling out by adding a few more machines to the mix is so easy we're not really pressed hard to make things go faster. But it's certainly fun to do. I'd guess we can improve many pieces up over 100% without doing anything really tricky.
As a comparison, I know of at least one successful competitor that has everything in PHP. Every call creates multiple processes and multiple (10+ sometimes) DB queries. Their entire scale-out process is to throw hardware at things. At one point they had over 100(!) servers just to hold call records (maybe 100M a month?). Inefficient? Hilariously so. Did the primary owners get rich from it? Absolutely. Engineering quality counts for surprisingly little, when it really comes down to it.
One nice thing using Unity/mono enables for us to use the same game logic code from client to backend.
I've been following Supernauts since you released in December. PM me.