Gleam Build Profiles: Transitioning from Dev to Prod for Erlang Targets
0 reputation · 06 Sept 2022, 18:59 UTC
0 reputation · 06 Sept 2022, 18:59 UTC
Gleam 1.0+ utilizes dev and prod build profiles within the gleam.toml configuration. The dev profile is designed to preserve debug information and disable specific optimizations to facilitate local development and debugging.
When switching to the prod profile, the compiler enables BEAM optimizations and strips metadata. While this improves performance, it alters the resulting bytecode and stack trace characteristics. There is a known risk that certain optimization flags may change tail-call optimization behavior, which could potentially impact the stability of recursive functions that were stack-safe during local development.
To ensure parity, it is necessary to verify that recursive logic remains stable under production-level optimization and that the absence of debug info does not hinder critical production telemetry.
prod profile introduce specific BEAM optimization flags that can alter tail-call behavior compared to dev?dev debug metadata?35275 reputation · 07 Sept 2022, 03:50 UTC
1. Does the prod profile add BEAM optimization flags that can alter tail‑call behavior?
Yes. In a prod build Gleam passes the Erlang compiler flags +native and, for BEAM targets, +{hipe,[o3]} (or a similar HiPE level depending on the OTP version). These enable native code generation and aggressive inlining. While the BEAM’s fundamental last‑call elimination remains active, the inlining can increase per‑call stack usage and, in extreme cases, shift the point at which the process stack limit is hit.
2. How to verify stack safety in a production build without relying on dev debug metadata?
Run a dedicated stress test that exercises the recursive function to a depth far beyond typical usage, monitor for system_limit errors, and optionally trace call depth with erlang:trace/3. The test should be performed on a prod‑built binary and, if needed, with the process stack size increased via the +P flag to confirm that the observed depth isn’t limited by defaults.
gleam build -t prod -v or set GLEAM_LOG=debug and capture the erlc command line. Confirm the presence of +native and +{hipe,…}.gleam build -t prod.system_limit or error_logger messages.erlang:trace(self(), true, [call]).
% run the recursive function
erlang:trace(self(), false, [call]).
Collect the trace events to compute the maximum call depth. Ensure it stays below ~80% of the configured process stack size.+P 32768 (or a value appropriate for your OTP). Repeat the test.gleam.toml:
[[profile.prod]]
erl_opts = ["+{inline,[{max_size,0}]}"]
This prevents the compiler from inlining recursive calls.To tailor these steps to your environment, I need to know which Erlang/OTP version you’re targeting. The exact HiPE level and native code flags can differ between releases, affecting the recursion depth that is safe.
Which Erlang/OTP version is your project built against?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.