Increased memory usage in Elixir/Phoenix app when following Neon.tech guide.
Hello,
I've noticed a significant (~200mb) increase in BEAM virtual machine ram usage (the heap, specifically) when following this guide: https://neon.tech/docs/guides/elixir-ecto
Previous to this updated guide, I believe the instructions were similar to the following:
This worked fine and I had no issues. Recently the guide has been updated as Postgrex 0.18 supports verifying the SSL certificate and your instructions now provide the following:
This is cleaner and preferred. The problem however is a seemingly large jump in ram usage. With the previous setup, my almost barebones Phoenix app is using only 74mb of ram according to the OTP Observer with 10 DBConnection processes. If I keep everything the same and switch to the new method, my ram usage jumps to ~254mb. I realize this is most likely not a you problem and I should file something with the Postgrex/Ecto repos but wanted to ask the following:
1) Have you heard reports of this or seen this occurring?
2) Is there a simple fix to this that I've missed?
I find it odd that this small change would drastically effect ram usage so much... I can't even start a simple app on Fly.io's 512mb machines anymore without going OOM unless I fallback to the older :verify_none guide.
Neon
Connect from Elixir with Ecto to Neon - Neon Docs
This guide describes how to connect from an Elixir application with Ecto, which is a database wrapper and query generator for Elixir. Ecto provides an API and abstractions for interacting databases, e...
4 Replies
rival-black•2y ago
Have you heard reports of this or seen this occurring?Hey! I personally haven't heard/seen many reports when it comes to increased memory usage when using Elixir
sunny-greenOP•2y ago
Thanks. I will issue something in the Ecto repo.
FYI @Mahmoud I've found out that this does indeed increase memory usage quite a bit. A better solution is to point to the SSL cert file itself, so that the string path gets copied, not the entire cert file into memory per elixir DBConnection process.
ssl: [cacertfile: "/etc/ssl/certs/ca-certificate.crt"]
or similar depending on where the cert file may be located. Above should be pretty standard on *nix
harsh-harlequin•2y ago
hey @Direwolf , following up here - are you thinking something along these lines? https://github.com/elixir-ecto/postgrex/issues/463#issuecomment-544412483
(note: I'm not super familiar with elixir but can work to get a docs pr started on our side)
GitHub
[Docs]: Configuring sslmode · Issue #463 · elixir-ecto/postgrex
I'm a bit confused on what the default sslmode is when ssl is specified. Is there any documentation on that, and any way to configure this option? Right now the docs just point you towards erla...
sunny-greenOP•2y ago
Sort of... this is more just a gotcha that was unexpected based on your docs @ https://neon.tech/docs/guides/elixir-ecto#configure-ecto. The behaviour itself might be intentional on the Ecto side, but if so, it seems like an oversight more than expected behaviour. The memory usage can be quite large when compared to not following your guide and using the previous old instructions.
Specifically on the link I just referenced, the code block that says
That last line for SSL should instead read:
At least that's where it was on my *nix container. I assume that's pretty standard but it's not a guarantee on every system. I think you should keep your docs as is but maybe put a little footnote explaining how memory usage might increase by calling :public_key.cacerts_get() and that the cacertfile option is a better one.
Truthfully I should really open this behaviour up as a question to the Ecto team and see if this is expected, or if perhaps, there's a better way to implement the storing of the return from :public_key.cacerts_get() . As is, it currently copies it into the memory space of each DBConnection process which seems wasteful. It should instead store it once, perhaps in an ETS table, and then have that table be referenced by each DBConnection process.