orestis

orestis

So I’m building a background service that periodically (once a minute) will reach out to a number of machines via HTTP or plain TCP. Each interaction should only take 100-200ms.

I’ve put each machine into each own GenServer and register those globally via Registry so I can reuse them and ensure that a) I don’t overwhelm a remote machine by accident, and b that requests for each machine will be serialized.

However, as the number of machines will scale to around 1000 (generous upper limit), I wonder if I will face the dreaded “out of file descriptors” error.

Since I’m being careful to not keep file descriptors open, I can always just bump the limit of file descriptors - but I wonder if there is any other hidden Erlang/Elixir limit I will hit before that.

I know there’s a port limit but that is be high (65k) and this VM doesn’t do anything else, so for plain TCP connections using :gen_tcp I should be fine.

For HTTP, I’m using straight HTTPPoison with the default options, which, as far as I can tell, doesn’t use any connection pooling. Now, I’m not sure whether I want to use HTTP keepalive, since I don’t trust the remote HTTP servers to do the right thing WRT to keep alive, and I don’t have control over them. I’ve seen weird bugs in the past.

Any other thing I should be aware of?

Showing Posts 1 to 10

OvermindDL1

OvermindDL1

The system ‘outgoing’ ports is significantly higher than 65k, you generally should not worry on outgoing connections.

However, to limit scale you can either have a single genserver that just holds, say, a map of active connections, waiting for messages about them, or use a connection pool like poolboy or so. :slight_smile:

sribe

sribe

The short answer is that no, there is no other limit than the ones you already know about.

The longer answer is that you may be uncomfortably close to some weird performance degradation that I haven’t yet figured out. Or not. I’d tell you the exact conditions that cause it, if I’d figured that out :frowning:

orestis

orestis OP

Have you run into this yourself? I’m not sure if you’re mirroring my sentiment (things might go wrong in unexpected ways!) or offering advice :slight_smile:

minhajuddin

minhajuddin

If you are using HTTPoison which uses :hackney. Make sure that you set max_connections to a high number. The default is 50. (config :hackney, max_connections: 1000). I think even open ports count towards the nofile ulimit. We ran into the :emfile issue while opening a lot of http connections. Also make sure that you read the response body so that the socket is freed up properly. If you make a request and don’t read the response body properly it tends to create issues.

sribe

sribe

Offering advice based on experience. Benchmark carefully. Benchmark at twice the load you expect to see if it falls apart.

steven7

steven7

I believe I am having a similar issue, but I don’t see this being reported on HTTPoison nor hackney. I still need more time in debugging this but do you still face the similar issue with the latest HTTPoison or hackney?

My use case is I would pattern match the HTTPoison.Response like such,

with {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- HTTPoison.get(url) do
 ...
else
{:ok, %HTTPoison.Response{status_code: code}} when code in [foobar] -> ...
_ -> ...
end

And I am getting a lot of weird :emfile error as well.

nikody

nikody

Are you making many concurrent requests? Also, are you on OS X? There is a 256 default limit for open file descriptors in OS X and a new connection in hackney, I believe, opens a new socket. I bumped into that problem recently.

steven7

steven7

Nope I am on Amazon Linux 2 (which is quite similar to CentOS 7).

minhajuddin

minhajuddin

An emfile error points to an incorrectly set ulimit (you can check your current ulimit by running ulimit -n, but make sure that you run it as the user that your app is running as) or you are not pooling your HTTP connections properly. Even with a default ulimit of 1024, you’ll hit the limit if you open up 1K http connections without a connection pool. So, to debug this, I would do the following:

  1. Figure out if you are using connection pooling in hackney
  2. Find out what the cause of the emfiles is: is it too many open http connections, too many open files?
  3. Use proper connection pooling and benchmark
steven7

steven7

I am indeed using connection pooling in hackney and I did set my ulimit to 500K beforehand so those are out of the way. Actually my observation is that when I ran lsof I can see that my “main” beam.smp is holding say, 800 TCP connections (which is well below the limit) but I do have some other Erlang-associated process such as 1_schedul, 2_schedul, ... and 1_dirty_c, 2_dirty_c, ... etc each holding an identical amount of TCP connections as my main beam.smp (I know they are associated with my main beam.smp because lets say my beam.smp PID is 4469, the PID of say 1_schedul would be 4469 some_other_number) and all of these add up to huge numbers.

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
ChrisAmelia
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication): toke...
New
dillonoconnor
Is there any way to avoid the Hologram compiler running when using iex? It seems like the front-end code could potentially be disregarded...
New
thiagogsr
** (ArgumentError) expected :max_attempts to be a positive integer, got: {:@, [line: 10, column: 19], [{:max_attempts, [line: 10, column:...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews