> But the speed and concurrency is no laughing matter. Miles and miles and miles ahead of ruby, python, etc in that matter.
People always make this comparison, which I feel is a bit weak/unconvincing. It's pretty easy to beat Ruby or Python in concurrency; most language runtimes do it.
Something most people might not realize is that Erlang/BEAM is miles ahead of even Java/the JVM, when it comes to operationalizing its concurrency — that is, building services that are robust in the face of heterogeneous workloads and misbehaving clients.
Ever tried to build a RESTful web service, that performs unpredictable-runtime tasks in response to user requests, but which budgets that runtime such that requests are hard-killed (and their resources freed) after a deadline, and/or if the client closes their TCP socket — even if they're in the middle of some some CPU-intensive hot loop — and which makes sure to "push down" that failure into resource-handles like DB sockets, such that the DB "sees" the failure and gives up on its related long-running CPU-intensive task as well?
This is a Hard Problem in Java, with a huge number of little considerations involved: lots of calls to Thread.interrupted; async requests; CompletableFutures; moving any parallel streams to their own explicit ForkJoinPools, etc. You can see the Project Loom team slowly giving the Java stdlib a working-over in this style, but even after their work becoming Generally Available, library authors will still need to do all this stuff as well.
In Erlang/Elixir, meanwhile: 1. the accepted TCP connection is a process, 2. the web request runs either inside it or in another process linked to it, such that either one dying kills the other, 3. any concurrent Tasks get linked to the TCP connection process that spawned them as well; 4. any DB calls temporarily link the checked-out DB connection to the request process as well; and 5. adding request deadlines is as easy as calling a function to spawn a deadline timer pointed at the spawning process's own head.
Essentially, idiomatic Erlang/Elixir code gets this type of robustness for free, with zero additional lines of code. The moment you have an Erlang web server, you have a robust Erlang web server.
(Erlang/BEAM is also miles ahead of Golang in operationalizing concurrency, for separate reasons, mostly to do with goroutine resource leaks. Separate topic, but I just figured someone would ask.)
And then there's the fact that per-process heaps mean most short-running request-response type workloads can get away with never making a garbage-collection call, instead just allocating a pre-sized arena with each process, doing work, and then tossing away that arena when the process quits. So, as long as you've built your Erlang/Elixir app idiomatically, doing each task in a process that doesn't survive the lifetime of the task — then you'll never see the same sort of gradual "putting off GC for later" asymptotic allocated-memory climb that you see in a most GCed languages.