# Precompilation after Julia Update

**URL:** <https://discourse.julialang.org/t/precompilation-after-julia-update/113792>\
**Category:** Tooling\
**Created:** [May 3, 2024, 12:30pm UTC](https://discourse.julialang.org/t/precompilation-after-julia-update/113792 "2024-05-03T12:30:36Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![roflmaostc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roflmaostc/32/30123_2.png) [@roflmaostc](https://discourse.julialang.org/u/roflmaostc)\
**Post date:** [May 3, 2024, 12:30pm UTC](https://discourse.julialang.org/t/precompilation-after-julia-update/113792/1 "2024-05-03T12:30:36Z")

</div>

Hi,

updating Julia versions can be annoying because precompilation for big projects take quite long.

I thought it’s clever to do the update, and then run a script which activates all my `dev` folders and instantiates them. That should trigger precompilation for many packages. Especially on my Laptop this seems to help a lot:

Just run this function, takes some minutes but then most of the stuff should be precompiled.

> **Old code, see updated below**
>
> ```julia
> using Pkg 
> 
> function precompile_dev_folders()
> cd("/home/fxw/.julia/dev")
> for folder in readdir()
> if isdir(folder)
> println("In folder: $folder")
> cd(folder)
> try
> Pkg.activate(".")
> Pkg.instantiate()
> try
> cd("examples")
> Pkg.activate(".")
> Pkg.instantiate()
> cd("..")
> catch
> println("No examples in $folder")
> end
> catch e
> println("Error in folder: $folder")
> println(e)
> end
> cd("..")
> end
> end
> end
> 
> ```

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [May 4, 2024, 3:24pm UTC](https://discourse.julialang.org/t/precompilation-after-julia-update/113792/2 "2024-05-04T15:24:01Z")

</div>

This seems particularly focused on developers.

I think you could adapt this to go through recent Manifest.toml usage by using `~/.julia/logs/manifest_usage.toml`

---

<div class="post-metadata">

**Author:** ![roflmaostc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roflmaostc/32/30123_2.png) [@roflmaostc](https://discourse.julialang.org/u/roflmaostc)\
**Post date:** [May 31, 2024, 9:36am UTC](https://discourse.julialang.org/t/precompilation-after-julia-update/113792/3 "2024-05-31T09:36:17Z")

</div>

Thanks for the tip!

```julia
using TOML
using Dates
using Pkg

"""
    precompile_envs(fname=".julia/logs/manifest_usage.toml"; 
                    time_diff=Dates.CompoundPeriod(Dates.Day(30)))

Precompile the environments listed in the TOML file `fname` if the last time they were used is greater than `time_diff`.
`fname` is the path to the TOML file that contains the information about the last time an environment on your machine was used.
As default `time_diff` is set to 30 days. 

So this script precompiles the environments that were used in the last 30 days. 
This is especially useful to save time after updating Julia.

"""
function precompile_envs(fname=".julia/logs/manifest_usage.toml"; time_diff=Dates.CompoundPeriod(Dates.Day(30)))
    # Load the project file
    toml = TOML.parsefile(fname)
    now = Dates.now()

    # Loop over the keys in the TOML file
    for key in keys(toml)

        for minor in deleteat!(collect(1:50), VERSION.minor)
            if occursin("/v1.$(minor)/", key)
                continue
            end
        end
        time = toml[key][1]["time"]

        try
            # if time difference greater than time_diff, precompile
            if now - time < time_diff
                # Precompile the project if possible and catch errors
                try
                    @info "Precompiling $key"
                    Pkg.activate(dirname(key))
                    Pkg.precompile()
                catch e
                end
                # deactivate the project
                Pkg.activate()
            end
        catch e
            if isa(e, InterruptException)
                @info "Interrupted"
                return
            else
                rethrow(e)
            end
        end
    end
end

```

---

<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:** [June 5, 2024, 11:00am UTC](https://discourse.julialang.org/t/precompilation-after-julia-update/113792/4 "2024-06-05T11:00:51Z")

</div>

It would probably be useful to exclude the default environments of earlier Julia versions from the script.

---

<div class="post-metadata">

**Author:** ![roflmaostc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roflmaostc/32/30123_2.png) [@roflmaostc](https://discourse.julialang.org/u/roflmaostc)\
**Post date:** [June 5, 2024, 12:30pm UTC](https://discourse.julialang.org/t/precompilation-after-julia-update/113792/5 "2024-06-05T12:30:47Z")

</div>

> [@roflmaostc](#):
>
> ```julia
> for minor in 1:(Int(VERSION.minor)-1)
> if occursin("/v1.$(minor)/", key)
> continue
> end
> end
> 
> ```

Yes, make sense!  
I think those lines should do it, I added it above.

---

<div class="post-metadata">

**Author:** ![cserteGT3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/csertegt3/32/8283_2.png) [@cserteGT3](https://discourse.julialang.org/u/cserteGT3)\
**Post date:** [June 5, 2024, 1:53pm UTC](https://discourse.julialang.org/t/precompilation-after-julia-update/113792/6 "2024-06-05T13:53:08Z")

</div>

Great tool! There’s a little typo in the function or the docs, as default `time_diff` doesn’t match.

I’ve opened an [issue](https://github.com/JuliaLang/Pkg.jl/issues/3146) at Pkg.jl long time ago for exactly this purpose, though it didn’t get attention and I haven’t reiterated it since. We could ask the devs if your implementation would be welcomed in the code.

I’ll definitely use it, thank you!

---

<div class="post-metadata">

**Author:** ![TheLateKronos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thelatekronos/32/12824_2.png) [@TheLateKronos](https://discourse.julialang.org/u/TheLateKronos)\
**Post date:** [June 11, 2024, 2:23pm UTC](https://discourse.julialang.org/t/precompilation-after-julia-update/113792/7 "2024-06-11T14:23:51Z")

</div>

It seems like this also precompiles environments with a different julia version than the currently active one:

```julia
julia> precompile_envs()
[ Info: Precompiling /home/dennishb/.julia/dev/Peaks.jl/Manifest.toml
  Activating project at `~/.julia/dev/Peaks.jl`
  Activating project at `~/.julia/environments/v1.10`
[ Info: Precompiling /home/dennishb/.vscode/extensions/julialang.language-julia-1.79.2/scripts/environments/languageserver/v1.10/Manifest.toml
  Activating project at `~/.vscode/extensions/julialang.language-julia-1.79.2/scripts/environments/languageserver/v1.10`
  Activating project at `~/.julia/environments/v1.10`
[ Info: Precompiling /home/dennishb/.julia/environments/v1.11/Manifest.toml
  Activating project at `~/.julia/environments/v1.11`
┌ Warning: The active manifest file has dependencies that were resolved with a different julia version (1.11.0-beta2). Unexpected behavior may occur.
└ @ ~/.julia/environments/v1.11/Manifest.toml:0
  Activating project at `~/.julia/environments/v1.10`
[ Info: Precompiling /home/dennishb/.julia/environments/v1.10/Manifest.toml
  Activating project at `~/.julia/environments/v1.10`
  Activating project at `~/.julia/environments/v1.10`

```

---

<div class="post-metadata">

**Author:** ![roflmaostc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roflmaostc/32/30123_2.png) [@roflmaostc](https://discourse.julialang.org/u/roflmaostc)\
**Post date:** [June 11, 2024, 2:46pm UTC](https://discourse.julialang.org/t/precompilation-after-julia-update/113792/8 "2024-06-11T14:46:25Z")

</div>

Are you using 1.10.4 and it compiled the `.julia/environments/v1.11`?

I think the for loop only skips versions below the current version but not higher.  
I just did a quick update.

---

<div class="post-metadata">

**Author:** ![TheLateKronos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thelatekronos/32/12824_2.png) [@TheLateKronos](https://discourse.julialang.org/u/TheLateKronos)\
**Post date:** [June 12, 2024, 2:27pm UTC](https://discourse.julialang.org/t/precompilation-after-julia-update/113792/9 "2024-06-12T14:27:36Z")

</div>

I first ran it with 1.10.4, then 1.11 beta, then did Pkg.update(), and then 1.10.4 again. The warning appears to have come because the environment was resolved when in the 1.11 channel (juliaup), which ended up in printing a warning when I went back to a previous julia version (1.10.4).

So I really abused it jumping julia version like that. But I was just thinking that a simple version check could make it robust also against such abuse. Otherwise, the function worked great, so thank you for posting it 😁

---

<div class="post-metadata">

**Author:** ![roflmaostc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roflmaostc/32/30123_2.png) [@roflmaostc](https://discourse.julialang.org/u/roflmaostc)\
**Post date:** [June 20, 2024, 3:15pm UTC](https://discourse.julialang.org/t/precompilation-after-julia-update/113792/10 "2024-06-20T15:15:32Z")

</div>

Now it is registered as PrecompileAfterUpdate.jl

> **[GitHub - roflmaostc/PrecompileAfterUpdate.jl: Precompile your recent...](https://github.com/roflmaostc/PrecompileAfterUpdate.jl)**
>
> Precompile your recent environments after a Julia version update - roflmaostc/PrecompileAfterUpdate.jl
