fireproofsocks
I thought I had a handle on how Elixir configuration worked, but now I’m thinking I missed something. My memory was that the config.exs file gets read at compile-time. So if my config.exs contained the following:
# config.exs
config :myapp, :foo, System.get_env("FOO")
Then I could compile an option into it via
FOO=bar mix compile
and starting up the app would yield the value that I set at compile time, e.g.
iex -S mix
# Expected:
iex> Application.get_env(:myapp, :foo)
"bar"
But the actual result is nil. Or whatever the System ENV is set to at runtime – and the app does not re-compile.
So my question is: is config.exs actually reading values at runtime? Or is it doing something special with System.get_env/2 so it resolves at runtime? Am I going crazy? I don’t remember it working this way. Thanks for any clarifications!
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
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
Hello,
I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New
Other Trending Topics
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
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #elixirconf-eu
- #metaprogramming
- #hex










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
v0idpwn
The environment is set by mix when starting up, both in compile time and when running your application. If you’re using releases, then the config is set at the point where the release is built (except for
runtime.exs, which is evaluated at startup in releases as well).al2o3cr
config.exsis still anexsfile, so it’s evaluated at runtime.My guess is that you’re remembering two similar things:
using
System.get_envin some places in modules will result in the “stay until the next compile” behavior you describe:SomeModule.foowill “capture” the value from ENV at compile-timeusing
System.get_envinconfig.exswill result in a “stay until the next release” behavior for environment variables, thus the need forruntime.exslud
@v0idpwn I am surprised actually, I too was believing that this was compile-time only but indeed the values defined here must be available at runtime and are not stored into a file like in a release.
So the runtime execution erases the value set before compilation.
What is confusing is that if you wanted to have this config:
And this code:
You cannot call
FOO=bar mix compileand then justiex -S mixand get the expected value, becauseiex -S mixwill always trigger a recompilation. The code above will emit a warning as you should useApplication.compile_env. Very different behaviour than calling@foo System.get_env("FOO")directly.Personnally, I just put everything possible in
runtime.exs.fireproofsocks
Thank you all for the input! @al2o3cr I know that putting
System.get_env/2anywhere outside of adefblock (e.g. in a module attribute) generally means it is evaluated at compile time (and the compiler now warns about this and it helpfully suggests usingApplication.compile_env/2instead).But I learned something from @v0idpwn : during regular development the
config.exsfile is read at runtime! What I was remembering was that during RELEASES, snapshots of the system ENVs are taken. So if you compile the app viaFOO=bar mix release, then the value of that ENV var is compiled into the app and even if you start the app with a different ENV value, e.g.FOO=ignored _build/dev/rel/myapp/bin/myapp start, it will use the value that was read as the time of compilation.Nicd
This is not true, no system env vars are implicitly baked into the release. If you read values from the env at compile time such as with
@foo System.get_env(…), then those values will be compiled into the code, but only because you did that.I also recommend using
config/runtime.exsfor everything that is not necessary to be set at compile time. It’s just less headache and surprises that way.l3nz
Tangentially, you may want to try SayCheezEx 📸 — say_cheez_ex v0.3.6 to get a friendlier approach to building environment/version strings.
v0idpwn
Yes, they are.
Quoting the documentation, here: mix release — Mix v1.12.3
Small demonstration:
Now, if I run:
You can see it was evaluated both at compile time and when starting the application with mix.
Now, I will generate my release:
You can see it was evaluated two times.
And run it:
You can see it was not evaluated, yet the result value is there.
Nicd
These are application environment values, not operating system environment variables.
v0idpwn
Ah, it seemed to me (and it still seems) that he was referring to when you read system env on application configuration, you’re effectively snapshotting it. Otherwise its pretty obvious that its read at runtime.
lud
The
IO.putshere is a placeholder forSystem.get_env