Recently got challenged by another Architect not familiar with Elixir(Golang background).
The test is very simple:
k6 to get .m3u8 file from my app ( small files need high RPS )
k6 to get .ts file from my app (bigger files, size around 2MB, this need high throughput )
For comparison:
Setup a Nginx and host two static files: one .m3u8 , one .ts
Basically in single machine by using k6:
for .m3u8, Nginx can get around 9600 RPS
for .ts, Nginx can get around 2500 RPS
for .m3u8, my app can get around 500 RPS
for .ts, my app can get around 500 RPS
Not surprise that I suspect the Elixir layer, so I added a Varnish layer front my app, and I got:
for .m3u8, Varnish can get around 9500 RPS
for .ts, Varnish can get around 2500 RPS
So this is on par with Nginx.
My questions is for actual application, how many RPS and throughput we expect ?
My person idea were around: anything should around 50% of Nginx performance.
I need your honesty advise, as this might affect Elixir usage in my company. I previously thinking move bytes around should not have performance issue in Erlang Beam.
A test with static files is not a good benchmark. For static files I would not consider using elixir but rather nginx,caddy,apache you name it. These web servers are excellent at serving static files. Furthermore, the tooling is better there. Phoenix is a framework to build a web application.
I actually pretty unsatisfy the result, so I built a Rust app return the same, Rust app can easily return around 6000RPS for .m3u8. So I am not surprise that the other Architect mentioned Golang can have 10 times RPS than my app.
Is there anything I can tune? or Anything I need to avoid ? thanks
10k RPS seems about what you would get due to the limits of TCP connections of 1 ip connecting to 1 ip:port combination. TCP is a complex subject beyond the scope of this thread and it seems your hitting that limit not the actual apps limit. The reason why I say this is if your getting 9k RPS serving a static file on a well maintained RUST webserver, the bottleneck is clearly not rust.
I would recommend running these tests over a unix streaming socket or if you need more largescale tests, to run them with large ip ranges connecting to the same ip:port combination. And measuring the speed serverside.
About that 300k RPS, I think its possible to get much more now with the JIT compiled VM and implementing zerocopy io_uring2 instead of using :gen_tcp or :socket. Tho using new :socket could produce much better results too.
The file actually not from file system, it is just binary get back from Riak KV, the size for .ts file is around 2MB. I cached it in Redis (want to improve the response time)
yes, K6 is tool in Golang as you provided the link.