Well to detail…
- Phoenix is a library of plugs and other helpers on the Plug library, it adds no overhead over Plugs.
- Plug is a library on Elixir for simple and fast web hosting, it adds a microscopic amount of overhead over the web server (cowboy), but buys a lot in safety.
- Cowboy is an Erlang web server library designed to handle any and all kinds of network communication as-fast-as-possible, a bit ugly of an interface because of that but it is fantastic in speed, Plug on top of it makes it blissful to use for most web protocols.
- Elixir is the language that compiles to the BEAM/EVM (Erlang Virtual Machine).
Asp.Net (the modern version, the older ones were utterly horrible) is a lot better now, but it breaks often (I know, we use it at work on some things that we cannot replace because Federal Laws…).
- .NET Core is basically mono and .NET merged, a making from when MS bought Xamarin(sp?), a normal Java-horrible-like GC’d VM, but decently fast.
Now, comparing parts to parts:
.NET Core vs BEAM/EVM:
- .NET Core will be faster on raw JIT performance, like processing numbers, but how often are you doing multi-dimensional matrix transforms in web hosting.
- BEAM/EVM barely has any JIT happening at all, but it is still very performant, however the language design combined with internal very low level async I/O allows the BEAM/EVM to outperform ‘almost’ anything on I/O (like networking, say, for webhosting) while being safer than any just about any language at all.
- However, .NET Core has very little ability to debug production, you mostly have to rely on your logs or hook up a debugger that often stops-the-world.
- Compared to the BEAM/EVM that has introspection that would make any network or server admin just drool, but it is done in a different way than you would do it on .NET Core (mostly because debugging individual instruction is as you would on .NET is hell for a concurrently real-time system).
If you need some really heavy processing, .NET is good, not great, I’d pick, say, Rust or C++ or OCaml or a host of other languages over ever touching .NET, but it is not bad. However a bad crash in it brings everything down, unlike on the BEAM/EVM where it is much safer in that it is expecting things to crash, and more importantly to handle it (not just talking about exceptions, also talking about, say, hardware failing). And if you need speed for something it is so trivial to plug in Rust or C++ or OCaml or even .NET to the BEAM/EVM via a Port (or for now kind of speed you can use any language that implements a C interface like C++ or Rust or OCaml to the BEAM/EVM as a NIF, but that incurs a hit on safety so be careful, Ports are almost always better).
Using Phoenix/Plug/Cowboy together, as they are always used together if using Phoenix, vs ASP.net they have significantly different styles of ‘work’, ASP.net’s is significantly more mutating, it can be hard to reason why something is changing where (as we’ve experienced innumerable times here at work), where in Phoenix the whole straight pipeline of Plugs is wonderfully immutable and you know where everything comes, no magic database access in views, no wondering why something is suddenly accessing the DB 20 times, no magic variables littered all over the place just to ‘tag’ crap, it just-makes-sense.
Basically for web hosting, the horizontal and vertical scaleability, for network usage, it is hard to beat Phoenix overall. Something may beat it in micro-tests like raw number performance or spamming out “hello world” to a port, but it is already close on all of those and with as close as it gets to them all with all the safety it has and scaling it has it is overall, in my opinion, unmatched, as well as it is trivial to interface it with other languages to do their specialty heavy-lifting, the BEAM/EVM makes a fantastic and safe ‘glue’ interface to other languages, even if the other languages did all the heavy work having them talk through the BEAM/EVM still gains you so much for server tasks.