ijunaidfarooq

ijunaidfarooq

Massive increase in binaries using Finch

I am using finch in my application, what my application do is:

It sends a request to the camera for getting a jpeg, (Basic/Digest auth) and get the binary image, and then send it to another cloud.

so if I have 500 cameras they are sending 500 * 2 requests per second.

I was using HTTPoison before and my binary state on phoenix dashboard was like this

but when I deployed with Finch.

I had these pool settings with hackney

  :hackney_pool.child_spec(:snapshot_pool, timeout: 50_000, max_connections: 10_000),
  :hackney_pool.child_spec(:seaweedfs_upload_pool, timeout: 50_000, max_connections: 10_000),
  :hackney_pool.child_spec(:seaweedfs_download_pool, timeout: 50_000, max_connections: 10_000)

and I have these settings with Finch now

  {Finch,
   name: EvercamFinch,
   pools: %{
     :default => [size: 500, max_idle_time: 25_000, count: 5]
   }},

I want to know the reason of such massive binary increase?

UPDATE:

this is what I am using to make requests

defmodule EvercamFinch do
  def request(method, url, headers \\ [], body \\ nil, opts \\ []) do
    transformed_headers = transform_headers(headers)

    Finch.build(method, url, transformed_headers, body)
    |> Finch.request(__MODULE__, opts)
    |> case do
      {:ok, %Finch.Response{} = response} ->
        {:ok, response}

      {:error, reason} ->
        {:error, reason}
    end
  end

  defp transform_headers([]), do: []

  defp transform_headers([{key, _value} | _rest] = headers) do
    case is_atom(key) do
      true -> transform_headers(headers, :atom)
      false -> headers
    end
  end

  defp transform_headers(headers, :atom) do
    headers
    |> Enum.map(fn {k, v} ->
      {Atom.to_string(k), v}
    end)
  end
end

This is how my process look for NimblePool

even with small size and count. why the NimblePool has increased to 2500+?

Most Liked

wojtekmach

wojtekmach

Hex Core Team

{scheme, host, port}

NobbZ

NobbZ

Then of course 2 pools are started. I already explained before the holidays in the slack that finch starts one pool per host/port combination. (There was also a 3rd key for the pool, but I do not remember it anymore)

keathley

keathley

I can’t really make a suggestion on your pools since it’s dependent on the servers that you’re interacting with and what they’re capable of handling. My suspicion is that the responses you’re dealing with are quite large (since you’re dealing with images) and the processes dealing with those responses aren’t being killed. Large binaries have historically caused issues for the garbage collector. I’m not sure if that’s changed in recent OTP releases or not. Killing the process can help reduce memory bloat. You can also use recon, observer, and the built in beam tools to try to track down which processes are causing you issues.

sb8244

sb8244

Author of Real-Time Phoenix

To expand on what Chris is suggesting. You can trigger GC manually across all processes by using Process.list() |> Enum.each(&:erlang.garbage_collect/1). If you do this and the memory drops, then you know you have a memory leak.

Here’s a post on an old memory leak I tracked down and some options for how to handler them https://stephenbussey.com/2018/05/09/elixir-memory-not-quite-free.html

keathley

keathley

It’s really hard to say without understanding what your code is doing. I have a general idea, but in this case the details matter. It would be useful to see which processes are using up the most memory. It’s definitely interesting and worth digging into, but I can only speculate without more information.

Where Next?

Popular in Questions Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
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
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New

We're in Beta

About us Mission Statement