shishini
Elixir vs Go Performance (Anton Putra)
I think this twitter post and youtube video didn’t get as much attention as I hoped
I am still new to Elixir, so can’t really judge
https://x.com/antonvputra/status/1865845828192977341
Its generally understandable that a compile statically typed language like go will be faster than Elixir (being dynamic and running on a vm) but I a bit surprised the availability performance
First Post!
ruslandoga
![]()
Some ideas:
settingit was already set+sbwt noneto avoid busy wait consuming the allocated CPU slice (might be irrelevant in this benchmark if there is no wait under load)ensuringshould be done automatically already: OTP 23 Highlights - Erlang/OTPSystem.onilne_schedulersis equivalent to the available CPUs inside the container- ensuring TCP socket options (recbuf (rcvbuf), sndbuf, backlog, reuseport, etc.) are the same for Go and Elixir
- switching to
:json - (possibly) disabling Logger or increasing the log level (is Go logging?)
- separating the Web and DB benchmarks to see where the slowdown is coming from
- (possibly) spawning processes handling the requests / connections with larger heaps to avoid reallocs
- (possibly) switching from Bandit to an alternative web server, I remember playing with an Elli-like HTTP/1.1 server and it was outperforming both Bandit and Cowboy in benchmarks with
wrk - (possibly) switching from Postgrex to an alternative PostgreSQL client and/or connection pool
- (possibly) running multiple Postgrex pools
However, all of these steps are not common among Elixir developers, so I think the benchmarked app is about as representative (of what we typically write) as it gets. And the benchmark itself highlights some areas for possible improvement ![]()
Most Liked
josevalim
Here is a pull request that makes the Elixir code closer to the code in Go and uses better defaults (for example, what Phoenix would have used): Make benchmarks with Elixir fairer by josevalim · Pull Request #370 · antonputra/tutorials · GitHub
josevalim
The issue is not Postgrex, but rather the fact it is comparing Ecto (which would be akin to a ORM):
With something that directly sends INSERT commands over the connection:
https://github.com/antonputra/tutorials/blob/main/lessons/230/go-app/device.go#L30-L33
And if you are going to set up 500 database connections, I would at least split over a few connection pools (by setting pool_count). Otherwise you are likely making the pool the bottleneck.
Overall, I’d expect the Go to have better throughput, but there is definitely a bit of apples to oranges going on. I honestly don’t understand why benchmark authors do not ask for some community vetting before publishing.
josevalim
Thanks for sharing. I am a bit surprised indeed the new round did not see any improvement, given my pull request yielded a 20-30% improvement locally. I cannot reproduce the failures from the first benchmark on my machine either, I even used a separate machine to push traffic locally and I get 80k req/s for Elixir vs 110k req/s in Go.
However, it is worth saying that it is 100% expected for Go to be faster than Elixir. After all, we are comparing a static imperative compiled language to a dynamic functional language running on a VM, so a reasonable difference (within the same order of magnitude) is expected. For example, TechEmpower main branch puts Go around 5x faster than Phoenix for single-query runs. I am mostly curious about the failure rate, which is not expected, but as far as I know, there is no way to reproduce the benchmarks and the production logs were not shared with us. So there isn’t much we can do at the moment.
Last Post!
outlog
- Only p90 is being tested/shown - way to low.
- A custom simple thrown together client is being used - most likely doing CO(Coordinated Omission) - eg. results are incorrect/misleading
- One system is mostly tested in overload >100% cpu (due to 1&2 nothing is really measured before overload occurs eg. latency 0?! ), the test is quickly stopped once the Go test reaches overload.
- The tests are out of sync, one test gets ahead of the other, for a given time.
Remedy:
- Use p99, or better measure the distribution.
- Use a proper client like Gatling (it even has an easy to use/install javascript tool these days: https://docs.gatling.io/tutorials/test-as-code/javascript/running-your-first-simulation/)
- Keep going into overload, for both systems.
- Solved by 2 - using a proper client.
So it’s all about using a proper load testing tool/client.
Popular in Discussions
Other popular topics
Chat & Discussions>Discussions
Latest on Elixir Forum
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










