# Startup time of 1000 packages – 53% slower in Julia 1.12 vs 1.10

**URL:** <https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343>\
**Category:** Internals & Design\
**Tags:** performance, ttfx, latency\
**Created:** [April 23, 2025, 7:36pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343 "2025-04-23T19:36:30Z")\
**Posts on this page:** 20\
**Page:** 4

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [October 13, 2025, 12:36pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/61 "2025-10-13T12:36:18Z")

</div>

jeez, @jules , give me a minute 😃

I modified the script to make sure the csv file is saved as well. Finished doing that 3 minutes ago, came to discourse to post that the aggregate data is now also available on the repo, and see that this was already announced 2 minutes ago by you.

I wish my students were as magically efficient and quick as this community (they are great anyway though)

---

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [October 13, 2025, 12:43pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/62 "2025-10-13T12:43:04Z")

</div>

PRs to the master branch that make `ttfx_snippets_vis.jl` better (called in `make_and_commit_plots.sh`) would be appreciated.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [October 13, 2025, 12:43pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/63 "2025-10-13T12:43:44Z")

</div>

Haha I didn’t know you had just set it up a minute ago, thanks for making that data available!

---

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [October 13, 2025, 12:51pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/64 "2025-10-13T12:51:04Z")

</div>

Here is the detailed runner info:

> **[Runner Server Configuration · JuliaEcosystemBenchmarks...](https://github.com/JuliaEcosystemBenchmarks/julia-ecosystem-benchmarks/discussions/4)**
>
> Ubuntu 2024 LTS 128GB ram AMD Ryzen 7 5700G More detailed info stefan@kr-amherst ~\> sudo lshw \[sudo\] password for stefan: kr-amherst description: Desktop Computer product: B550M AORUS PRO-P (Defaul...

Summary

Ubuntu 2024 LTS

128GB ram

AMD Ryzen 7 5700G

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [October 13, 2025, 1:03pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/65 "2025-10-13T13:03:25Z")

</div>

I was thinking something like this:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/f/e/fe19ea14b4e2c72d2997436c973d8a6aa6ac863c.png)

> **Code**
>
> ```julia-auto
> pdd = CSV.read(Downloads.download("https://raw.githubusercontent.com/JuliaEcosystemBenchmarks/julia-ecosystem-benchmarks/refs/heads/jeb_logs/data/Julia-TTFX-Snippets/ttfx_snippets_data.csv"), DataFrame)
> 
> pddg = combine(groupby(pdd, [:package_name, :julia_version]), :precompile_time .=> [minimum, mean, median, maximum])
> 	
> pgn = pddg[pddg.package_name .== "BaseDirs", :]
> sort!(pgn, :julia_version)
> barplot(pgn.precompile_time_mean, label = "Mean",
> axis = (; xticks = (1:nrow(pgn), pgn.julia_version), xticklabelrotation = π/4,
> xlabel = "Julia version", ylabel = "Precompile time (seconds)")		
> )
> rangebars!(1:nrow(pgn), pgn.precompile_time_minimum, pgn.precompile_time_maximum, color = :red, linewidth = 1, whiskerwidth = 10,
> label = "Min-max range")
> axislegend()
> current_figure()
> 
> ```

---

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [October 13, 2025, 1:13pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/66 "2025-10-13T13:13:44Z")

</div>

That is great, here are a few comments:

- The named versions `alpha`, `lts`, etc, probably need to be filtered out or changed to include only the last handful of results because `lts` includes all versions that were historically lts, not just the current lts (some for the other named versions)
- Median might be better than mean because there are a ton of extreme outliers
- If someone gets around to submitting this as a PR it will be accepted quickly and will be present in the autogenerated plots (see `ttfx_snippets_vis.jl`)

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [October 13, 2025, 2:24pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/67 "2025-10-13T14:24:46Z")

</div>

maybe it would make sense to store commit hashes or something for the changing specifiers? Otherwise it gets a bit complicated to map them back I guess

---

<div class="post-metadata">

**Author:** ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)\
**Post date:** [October 13, 2025, 3:13pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/68 "2025-10-13T15:13:29Z")

</div>

That is available deep in the logs and can be added to the csv (at some point).

---

<div class="post-metadata">

**Author:** ![RomeoV](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/romeov/32/37687_2.png) [@RomeoV](https://discourse.julialang.org/u/RomeoV)\
**Post date:** [October 13, 2025, 7:25pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/69 "2025-10-13T19:25:29Z")

</div>

The discussion seems to be burying the lead a bit - from the plot it looks like 1.12 does not have a major regression compared to 1.10, correct?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [October 13, 2025, 9:12pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/70 "2025-10-13T21:12:49Z")

</div>

If I look at my CI jobs:

> <https://github.com/OpenSourceAWE/KiteModels.jl/actions/runs/18406386742/job/52447178480>

> <https://github.com/OpenSourceAWE/KiteModels.jl/actions/runs/18406386742/job/52447178473>

They need 26 min with Julia 1.10 and 31.5 min with Julia 1.12. A difference of 20%. But this is, of course, only one measurement, not necessarily representative.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [October 13, 2025, 9:29pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/71 "2025-10-13T21:29:01Z")

</div>

And when I do the same comparison with GMT it takes ~12-13 minutes with 1.10 and 24-25 with 1.11. 1.12 and nightly.

And this despite significant improvements achieved after important reductions in invalidations on 1.12.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [October 14, 2025, 12:46am UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/72 "2025-10-14T00:46:11Z")

</div>

> [@joa-quim](#):
>
> And when I do the same comparison with GMT it takes ~12-13 minutes with 1.10 and 24-25 with 1.11. 1.12 and nightly.

Did you create an issue for this regression at [GitHub · Where software is built](https://github.com/JuliaLang/julia/issues) ?

---

<div class="post-metadata">

**Author:** ![christiangnrd](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christiangnrd/32/215467_2.png) [@christiangnrd](https://discourse.julialang.org/u/christiangnrd)\
**Post date:** [October 14, 2025, 1:22am UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/73 "2025-10-14T01:22:42Z")

</div>

I just switched over our benchmark CI to 1.12. Over 1.12, Import is a 10% improvement, precompile is a slight regression, and TTFX (compiling an empty kernel) takes 55% longer

> **[Benchmarks](https://metal.juliagpu.org/bench/)**

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/224680_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [October 14, 2025, 5:34am UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/74 "2025-10-14T05:34:51Z")

</div>

For DifferentiationInterface, the regression can be really visible in my current CI runs ([chore: switch to Runic formatting from JuliaFormatter (#871) · JuliaDiff/DifferentiationInterface.jl@7a87b5f · GitHub](https://github.com/JuliaDiff/DifferentiationInterface.jl/actions/runs/18465042570)):

- SimpleFiniteDiff backend:
  - 1.10: 58m
  - 1.11: 1h19
  - 1.12: 1h27

- ForwardDiff backend:
  - 1.10: 43m
  - 1.11: 59m
  - 1.12: 55m

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [October 14, 2025, 2:24pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/75 "2025-10-14T14:24:41Z")

</div>

> [@ufechner7](#):
>
> Did you create an issue for this regression at [GitHub · Where software is built](https://github.com/JuliaLang/julia/issues) ?

Not particularly this one but for example [#59494](https://github.com/JuliaLang/julia/issues/59494), where with the very helpful contibutions of Kristoffer and Tim the TTFP of the plot function dropped down to the amazing:

```julia-auto
julia> @time using GMT
  0.707362 seconds (1.11 M allocations: 64.533 MiB, 5.06% gc time, 3.01% compilation time)

julia> @time @eval plot(rand(5,2))
  0.002897 seconds (721 allocations: 34.281 KiB)

```

This is very likely fastest TTFP of a _plot()_ function in Julia. But unfortunately this does not propagate and a call that is almost identical in called functions (it differes to only one line)

```julia-auto
julia> @time @eval bar(1:5, (20, 35, 30, 35, 27), width=0.5, color=:lightblue, limits=(0.5,5.5,0,40))
  0.625434 seconds (2.13 M allocations: 108.216 MiB, 6.82% gc time, 98.59% compilation time)

```

compiles again. Sure, I can add this one too to the pre-compile workload but just that extra line adds 500 kb to the pre compiled cache. The size of the pre-compiled cache is what stops me to add much more to `PrecompileTools` workload. I have codes with a couple hundreds LOC that add ~10 MB to the pre-compile cache. I really don’t understand what happens in this land, only that they are **huge**.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [October 14, 2025, 5:13pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/76 "2025-10-14T17:13:13Z")

</div>

> [@joa-quim](#):
>
> I really don’t understand what happens in this land

What you describe here is probably not directly related to the compile times of packages. I am still looking for a simple, small, reproducible test case for the compile time that shows an increase of more than 20%. Then we would have the chance to create an issue that might get addressed.

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [October 14, 2025, 5:25pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/77 "2025-10-14T17:25:53Z")

</div>

This is likely influenced by how you specialize to kwargs in your code.  
In makie we try do convert to untyped dicts for kwargs as early in the call as possible, so that all inner functions don’t specialize to the kwargs.  
I’m not sure if that helps with gmt, but without it I’m sure you’ll get larger precompile times with slightly different kwargs!

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [October 14, 2025, 5:33pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/78 "2025-10-14T17:33:58Z")

</div>

I think that what you mean is more or less what I do here

> <https://github.com/GenericMappingTools/GMT.jl/blob/master/src/psxy.jl#L11-L20>

The `_common_plot_xyz()` is the big function that does most of the parsing work. I still have to keep a `Dict{Symbol, Any}` because input can take different forms. But one thing that puzzles me is that other functions that rely almost ti calls to this main function still compile sub-functions that should have been already precompiled (at least they do not show up as invalidations with SnoopCompile)

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [October 16, 2025, 7:54pm UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/79 "2025-10-16T19:54:15Z")

</div>

Not just startup times are increasing. The runtimes are getting worse too. I have a couple of tests in GeoStatsFunctions.jl that are now failing in Julia v1.12:

```julia
CompositeVariogram: Test Failed at /home/runner/work/GeoStatsFunctions.jl/GeoStatsFunctions.jl/test/theoretical/composite.jl:102
  Expression: #= /home/runner/work/GeoStatsFunctions.jl/GeoStatsFunctions.jl/test/theoretical/composite.jl:102 =# @elapsed(sill(γ)) < 1.0e-5
   Evaluated: 0.007924943 < 1.0e-5

```

I didn’t change a single line of code 😟

P.S.: the elapsed test is placed after a warmup call, so it is not measuring compilation.

---

<div class="post-metadata">

**Author:** ![hz-xiaxz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hz-xiaxz/32/209585_2.png) [@hz-xiaxz](https://discourse.julialang.org/u/hz-xiaxz)\
**Post date:** [October 17, 2025, 2:12am UTC](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343/80 "2025-10-17T02:12:12Z")

</div>

Oh that’s quite servere, some should look into it.

[Previous page](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343.md?page=3)

[Next page](https://discourse.julialang.org/t/startup-time-of-1000-packages-53-slower-in-julia-1-12-vs-1-10/128343.md?page=5)
