Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I'm not too familiar with Scala nor Akka, but know that Akka uses the actor model for concurrency. How does it differ from Erlang/Elixir?


In Akka, multiple actors share a pool of threads. This has a lot of implications:

1. Garbage Collection. Garbage Collection on the JVM is not isolated to actors. One actor causing a lot of memory churn will prompt a garbage collection and prevent all other actors from executing until the Garbage Collector is finished. BEAM (the erlang VM) has per process (aka per actor) garbage collection, so actors will not interfere with each other during garbage collection.

2. Shared Memory. Since the JVM does not provide proper isolation guarantees, actors can in fact access shared memory. Safety in concurrency is accomplished via best practices rather than guaranteed by the VM. The BEAM VM does not allow shared memory. It is impossible for two processes to write to the same memory. While this matches the convention in Akka, it is enforced at the VM level.

3. Scheduler. In Akka, actors are oversubscribed to threads. That's why you can have hundreds of thousands of actors on a single system. The abstraction is great, but the implementation means that calling Thread.sleep is going to tie up a thread. If you do that often enough then all the threads will get tied up and the rest of the actors will be unable to make progress. The BEAM VM handles this scheduling at a much lower level. Calling sleep on an Erlang process is no big deal. While sleep is a contrived example, the effect on the ecosystem is pretty big. Using a blocking HTTP client on Akka is a bad idea. You have to use something like Dispatch or Spray which is essentially callback based (via monadic Futures). In Erlang, you just make the blocking call and the scheduler takes care of it. Since the synchronous code is easier to reason about than asynchronous code, the Erlang solution is simpler, easier to maintain and often more performant.

I've spoken with a number of seasoned Scala/Java programmers who basically tell me "Of course you shouldn't do that, just do X or Y". With Erlang, I find there are fewer situations where you need to be an expert to avoid screwing things up.


3 is true because Actors are implemented on top of a language and runtime that hasn't decided to implement actors and ONLY actors. Just like Haskell, you can in fact mix paradigms of concurrency. This is generally regarded to be a positive thing! But of course it does mean you need to understand how the semantics interact.

But it's weird to call out actors oversubscribing to threads in Akka as a bad thing when that's exactly what Erlang's runtime does! And by the way, it's not difficult for even C to match the classic "quarter million execution threads" claim. Java certainly can with competitive memory overheads.


The problem with Akka oversubscribing is that it doesn't actually have control over execution. It can't pause an actor in order to guarantee fair scheduling. It's similar to Node and the event loop in that regard. That's a big deal in my book.

Competitive memory overhead in the Erlang world for a quarter million processes is 700MB (just sleeping). You can't do that with POSIX threads, where the default pthreads stack size on Linux is 2MB. Java adds more overhead on top of POSIX threads. As far as tuning PTHREAD_STACK_MIN on x86 is generally 16K, which is quite a bit bigger. So either you aren't in the same ballpark (factor of >5) or you have basically built a scheduler yourself (which is what Akka did).


> The problem with Akka oversubscribing is that it doesn't actually have control over execution. It can't pause an actor in order to guarantee fair scheduling. It's similar to Node and the event loop in that regard. That's a big deal in my book.

I mean it can if you use their libraries. You just suggest that because calling out to a different I/O library is possible that we should only evaluate it in that context. This is basically a condemnation of ALL languages that host multiple abstractions.

> or you have basically built a scheduler yourself (which is what Akka did).

Riiiiiiight.. so... what's the problem there? Someone did what the erlang folks did on the JVM. Why is that used as a refutation here?

> As far as tuning PTHREAD_STACK_MIN on x86 is generally 16K, which is quite a bit bigger. So either you aren't in the same ballpark (factor of >5)

My comment was in regards to building a scheduler yourself (erlang doesn't have that many threads of parallel execution either) or using a technique with less demanding semantics like Fork-Join.

A lot of people have mixed up a lot of concepts here in the attempt to discuss why they like Erlang, but the truth is that it can't be nearly so efficient at scheduling and executing parallel computation as the average Java program appealing to java.util.concurrent, but is tuned for greater concurrency. It's also true that for some classes of computation Erlang's strategy works great, and for others it'd require substantial engine improvements to make competitive.

The impression given on this thread is that Elixir is the answer. I don't like that impression being left for people new to the discipline, because it's not how most people who are good at distributed systems or massively parallel AND concurrent programming think about the problem.


By not having preemptive scheduling, there are a whole lot of hoops that have to be jumped through. Spray.io is a disaster in usability in my opinion, for example. I've yet to find my code simpler and easier to maintain and debug when I use callback based async techniques. That is, however my opinion and personal taste. Others may disagree.


You won't find me carrying a lot of water for any Node library.

I just think it's not wise to try and represent the use cases that actor based excels at as primary for our industry or even somehow privileged.


The difference is the scheduling. In erlang, processes are preemptively scheduled, in akka they aren't. Erlang goes to great lengths to avoid one process from starving another. With akka you have to go to some lengths yourself to prevent starvation (e.g. preventing blocking calls in your event handlers).




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: