newton-peixoto

newton-peixoto

Speed difference between chunk http response and non-chuncked

Hello everyone I’m studying about http streams and I notice a big difference in performance when returning everything at once and when streaming and that made me think if streaming a big file is really worth it or if there is something wrong with my implementation (most likely that haha) So if anyone could help me understand this situation I’d appreciate a lot. Thanks

non-stream implementation

  get "/no-stream" do
    pokemons = File.read!("file.json")
    conn |> send_resp(200, pokemons)
  end

Stream implementation :

  get "/" do

    conn = conn
    |> put_resp_content_type("text/event-stream")
    |> put_resp_header("Access-Control-Allow-Origin", "*")
    |> send_chunked(200)

    File.stream!("file.json")
    |> Jaxon.Stream.from_enumerable
    |> Jaxon.Stream.query([:root, :all])
    |> Stream.map(fn element ->
     {:ok, pokemon}  = Jason.encode(element)
      conn |> chunk(pokemon <> "\n")
    end )
    |> Stream.run

    conn
  end

As you can see the stream implementation has a latency MUCH higher even though the memory peak is a little bit lower. The question here is trying to understand if this is normal or if I messed up somehow I understand if is not possible to achieve the same latency as File.read! but the difference here is so high that made me wonder if something if off

BTW: the lib used to run the load test is called hey

Most Liked

kip

kip

ex_cldr Core Team

When I think about when to stream I think of three cases:

  1. Time-to-first pixel is more important that absolute throughput. By streaming the user may be able to see something after the first chunk. In non-streaming the whole content has to arrive first. Very use case dependent.

  2. The content is being streamed from an external source (like S3) to Elixir and then transformed before sending to the HTTP client. In this case streaming may be more memory efficient and the stream-in/stream-out may manage the upstream latency and bandwidth better.

  3. The size of the content to be sent is non-trivial in terms of memory availability on the Elixir system. (as you’ve already pointed out).

I appreciate some of this may be more theoretical benefit rather than practical benefit so as always, testing and measuring is important.

kwando

kwando

Looks like your streaming version does more work tbh, parsing and encoding JSON..

Also I believe send_file would be even faster :slight_smile:

Where Next?

Popular in Questions Top

marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lists...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: The documentation above suggests that while ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New

Other popular topics Top

New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement