odarriba

odarriba

Elixir 1.9 release slow boot time

Hello,

We are working in a pretty big Elixir application (at the moment of writing, 1 minute of compilation in an i5 processor and ~930 modules) and we have recently moved from Distillery to new Mix releases.

The issue we are having is that we are experiencing a 300% extra boot time in the application, which is causing some problems on our deployments (but we can fix that, the deployment is not the issue).

We have made a comparision of booting times with a release made by Distillery and a release made by new Mix release command, and we are seeing:

  • Distillery: ~2 seconds until Phoenix is up, inluding checking for pending migrations
  • Mix: ~9 seconds until Phoenix is up, without any migration-related process.

both measurements are on the same machine (which is the same I have made the build, so no cross-platform issue)

I have tries removing all runtime configurations, which make irt a bit better (1 or 2 seconds less) but not even near Distillery times.

Also, I noticed that during Mix release boot there is only one BEAM process taking 150% of CPU for that ~9 seconds, when with Distillery one dont get to that usage (or it goes so faster that top doesn’t measure it).

Our mix.exs release config:

  def project do
    [
      ...
      releases: [
        my_release: [
          include_executables_for: [:unix],
          path: "rel/build/my_release"
        ]
      ],
      default_release: :my_release,
      ...
    ]
  end

vm.args.eex is like the default one and the env.sh.eex just set the distribution to name and sets the node name according to the pod IP when deployed on kubernetes (that was also made on Distillery releases).

Note that we are doing all this benchmarks on local, not even deploying to Kubernetes (which quotas configuratiuons can also affect).

Any idea what is happening?

Most Liked

odarriba

odarriba

Yep, we are using Erlang 22 with Elixir 1.9.0 (we also tried 1.9.1)

In development we are using:

elixir 1.9.0-otp-22
erlang 22.0.5

and in production we build using official elixir image.

However, the compilation times are the expected ones (more or less, it takes time but it’s due to cross dependencies between modules), the issue is when we start the release itself, that produces a CPU spike and a quite long time until the first request is served, which doesn’t happen with Distillery.

tcoopman

tcoopman

Ok, so I’ve created a bunch of test cases and measured the time to entry in Application.start:

## Distillery (elixir 1.8.2-otp-21)
- date && _build/prod/rel/app/bin/app foreground: < 3 seconds
- date && _build/prod/rel/app/bin/app console: < 3 seconds

## Distillery (elixir 1.9.1-otp-21)
- date && _build/prod/rel/app/bin/app foreground: < 3 seconds
- date && _build/prod/rel/app/bin/app console: < 3 seconds

## Elixir releases (elixir 1.9.1-otp-21)
- date && _build/prod/rel/app/bin/app start: 10 seconds
- date && _build/prod/rel/app/bin/app start_iex: 10 seconds

## env MIX_ENV=prod mix phx.server --preload-modules (elixir 1.9.1-otp-21)
- date && env MIX_ENV=prod mix phx.server --preload-modules: < 3 seconds

## Experiment: Elixir releases without runtime configuration (elixir 1.9.1-otp-21)
- date && _build/prod/rel/app/bin/app start: < 3 seconds

As you can see, the Elixir releases with runtime configuration are way slower than distillery (which has the same runtime configuration). By accident I tried releases without runtime configuration and noticed this was much faster (in the same range as distellery - my feeling says it’s still a bit slower, but hard to measure/benchmark correctly so don’t trust me on this)
(Just as confirmation, my runtime configuration does nothing special, only reading environment variables and parsing a 4 values to Integer. It’s the same configuration that I use in distillery as well)

I’ve also tried: env MIX_ENV=prod mix phx.server --preload-modules which should preload and the startup speed is in the same ballpark as distillery, releases without runtime configuration.

So my conclusion is that there is something wrong with elixir releases with runtime configuration.
Maybe that’s easier to confirm for someone else?

odarriba

odarriba

This happens to me also, it’s a private project with a high number of modules, and cannot publish it open source.

However I see the same issue you are having, but in a different scale (because of the number of modules, which is totally understandable).

As @jola said, it is expected that Releases take longer than mix phx.server, the real issue is that mix releases are taking 3x time the start time of a distillery release in some scenarios (we have 4 elixir projects in prod, and only this one is suffering this issue).

In our particular case, we tried removing some aspects like external libraries (AppSignal for example) in case it was causing some trouble starting the agent… but no luck. We end up rolling back to distillery until this gets solved or we have more time to investigate more to fill a proper issue in the core.

if someone thinks about anything we can look at, I will be pleased to try things.

jola

jola

Releases should start slower than mix phx.server because they preload modules. Mix will load modules lazily, so it starts instantly but you get a slower application until all modules have been loaded instead. Because releases preload modules they start slower but are then “warm”. Releases also start twice, once to load runtime configuration and the second time for real.

It’s hard to know in your case if mix releases are slower than distillery, unless you have a comparison?

jola

jola

Best thing would be to set up a repo that reproduces it. The core team would probably be happy to look at it.

I hope you find an answer :slight_smile:

Where Next?

Popular in Questions Top

lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
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
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
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New
jc00ke
Expanding on this topic: https://forum.elixirforum.net/t/map-typespec-question/19217 Let’s say I have a map with required and optional k...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
idi527
I’ve been re-reading swift book again and noticed that multiline strings there don’t have a trailing line break, unlike in elixir iex(2)...
New

Other popular topics Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
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
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
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
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

We're in Beta

About us Mission Statement