# Does resolve respect JULIA\_PKG\_PRESERVE\_TIERED\_INSTALLED?

**URL:** https://discourse.julialang.org/t/does-resolve-respect-julia-pkg-preserve-tiered-installed/138389
**Category:** General Usage
**Created:** [July 21, 2026, 7:19am UTC](https://discourse.julialang.org/t/does-resolve-respect-julia-pkg-preserve-tiered-installed/138389 "2026-07-21T07:19:58Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [July 21, 2026, 7:19am UTC](https://discourse.julialang.org/t/does-resolve-respect-julia-pkg-preserve-tiered-installed/138389/1 "2026-07-21T07:19:58Z")

</div>

`JULIA_PKG_PRESERVE_TIERED_INSTALLED` is mentioned in the docs for `] add`.  
But this is not the only way packages get installed.

A particular case I am interested in is `resolve`.  
If you delete the Manifest.toml and run `resolve` it will install all the dependancies.  
I want to know if setting `JULIA_PKG_PRESERVE_TIERED_INSTALLED` will actually work to make it select ones i have installed for some other project or not.

I feel like it should.

It’s really hard to test this, and I haven’t been able to find where in the source code `] resolve` decided to install things, to see what options it uses.

---

<div class="post-metadata">

### Author: ![PatrickHaecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickhaecker/32/222891_2.png) [@PatrickHaecker](https://discourse.julialang.org/u/PatrickHaecker)
#### Post date: [July 23, 2026, 3:46am UTC](https://discourse.julialang.org/t/does-resolve-respect-julia-pkg-preserve-tiered-installed/138389/2 "2026-07-23T03:46:22Z")

</div>

It’s queried via `default_preserve()`, which is called iff `add` or `develop` are called. I am not especially familiar with that part of `resolve`, but I think the answer is: no.

However, I wouldn’t even know how it could preserve the versions after the manifest has been deleted. In my book deleting the manifest means: “Start from scratch – I don’t care whether there is any similarity to what we had before”. So I think this combination would depend on you not deleting the manifest.

In general it’s my experience that the ~~more exotic~~ rarely tested combinations of Pkg.jl typically don’t work as you’d hope. Instead of complaining I [started to create a PR](https://github.com/JuliaLang/Pkg.jl/pulls?q=is%3Apr+author%3APatrickHaecker) whenever I identified such a shortcoming in our use cases and I encourage everyone to do the same.

That being said, I think we have a serious lack of review time in Julia, which especially shows there. As reviewing is not the favorite activity for most developers, I am not sure whether we can solve this without having people doing this during their paid time, especially as the imbalance increased with LLMs making it much easier to create code, but not so much easer to review code.

Anyway: If you have commit permissions to accept PRs in `JuliaLang`, please consider reviewing some Pkg.jl PRs. A nearly three digit number of open PRs is definitely too much for a project of that size (around 1 open PR per 200 lines of regular code).

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [July 24, 2026, 1:40am UTC](https://discourse.julialang.org/t/does-resolve-respect-julia-pkg-preserve-tiered-installed/138389/3 "2026-07-24T01:40:35Z")

</div>

> [@PatrickHaecker](#):
>
> However, I wouldn’t even know how it could preserve the versions after the manifest has been deleted. In my book deleting the manifest means: “Start from scratch – I don’t care whether there is any similarity to what we had before”. So I think this combination would depend on you not deleting the manifest.

`JULIA_PKG_PRESERVE_TIERED_INSTALLED` has 2 parts to it.  
1 is the **preserve** which as you say needs the manifest, because it wants to minimise changes to preserve what is in the manifest.  
But the other is the **installed** which doesn’t depend on the manifest, it depends on what else is already installed on your system.  
And that’s actually the feature i am interested in.

---

<div class="post-metadata">

### Author: ![PatrickHaecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickhaecker/32/222891_2.png) [@PatrickHaecker](https://discourse.julialang.org/u/PatrickHaecker)
#### Post date: [July 24, 2026, 3:45am UTC](https://discourse.julialang.org/t/does-resolve-respect-julia-pkg-preserve-tiered-installed/138389/4 "2026-07-24T03:45:29Z")

</div>

> [@oxinabox](#):
>
> But the other is the **installed** which doesn’t depend on the manifest, it depends on what else is already installed on your system.  
> And that’s actually the feature i am interested in.

Ah, I see. Thanks for the explanation. Yes, this could work. Although a ton of questions need to be answered (What if multiple versions of a package are installed in other environments? What if installed versions of different packages across different environments are incompatible to each other?).

May I ask what the use case is? I am wildly speculating, but it is too much fun not to do so 😉 : It does not seem to be “get the (hopefully) most bug-free, because most-recent version”. It does also not seem to be “get the package versions with known bugs in their interplay”. It rather sounds like “I have a really slow downstream and I don’t care which bugs I get, I just want to get this up and running as quickly as possible”. But then again why not start from a hopefully known-good manifest?

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [July 28, 2026, 1:21am UTC](https://discourse.julialang.org/t/does-resolve-respect-julia-pkg-preserve-tiered-installed/138389/5 "2026-07-28T01:21:42Z")

</div>

> [@PatrickHaecker](#):
>
> Ah, I see. Thanks for the explanation. Yes, this could work. Although a ton of questions need to be answered (What if multiple versions of a package are installed in other environments? What if installed versions of different packages across different environments are incompatible to each other?).

> Ah, I see. Thanks for the explanation. Yes, this could work. Although a ton of questions need to be answered (What if multiple versions of a package are installed in other environments? What if installed versions of different packages across different environments are incompatible to each other?).

Presumably those are all already determines by the behavour of JULIA\_PKG\_PRESERVE\_TIERED\_INSTALLED with `]add`.

> May I ask what the use case is?

The use case two things.

1. I am mostly using very well established features of packages, but i am using them within a huge dependancy tree. Most of the stuff I am doing depends on Catalyst.jl, which has **153** dependancies, and Plots.jl which has **167** indirect dependancies. (and together they have **310** net). That is 10-20 minutes pre-compile time. I often want to create a little enviroment (maybe with `]activate --temp`) to test something out, or make a MWE. I would like to minimise my precompilation time, I don’t want to get the latest feature i won’t use from some dependenancy of a dependancy.

2. As a hack around the fact that pyjuliapkg does not support Manifest.toml for the julia enviroment it creates ([equivalent of Manifest.toml / pixi.lock · Issue #78 · JuliaPy/pyjuliapkg · GitHub](https://github.com/JuliaPy/pyjuliapkg/issues/78)). So if anything indirect gets a release and the enviroment needs to be resolved (which i think is needed all the time on CI) we install it, which voids the precompilation cache. if the resolving was to do as per preserve installed tiered, then it would preferentially use installed packages (and on CI `julia-cache` does cache not just compilations but also installation). And the latest installed packages would generally end up being a set that was precompiles together last time, before that release.

---

<div class="post-metadata">

### Author: ![PatrickHaecker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/patrickhaecker/32/222891_2.png) [@PatrickHaecker](https://discourse.julialang.org/u/PatrickHaecker)
#### Post date: [July 28, 2026, 9:55am UTC](https://discourse.julialang.org/t/does-resolve-respect-julia-pkg-preserve-tiered-installed/138389/6 "2026-07-28T09:55:14Z")

</div>

Thanks for the explanations. Indeed, interesting use cases and I can now totally see where you are coming from.

> [@oxinabox](#):
>
> I often want to create a little enviroment (maybe with `]activate --temp`) to test something out, or make a MWE. I would like to minimise my precompilation time […].

Have you considered using [stacked environments](https://docs.julialang.org/en/v1.14-dev/manual/code-loading/#Environments) together with a temporary environment? As far as I know they only work in REPL-only workflows, but I guess this is the typical workflow for a temporary environment anyway.

> [@](#):
>
> So if anything indirect gets a release and the environment needs to be resolved (which i think is needed all the time on CI) we install it, which voids the precompilation cache.

I think using `resolve` on CI is at least problematic and it helps to think about the implications.

- For app packages (anything which is meant to be started directly and not included into something else, so not limited to what `Pkg` calls “app”) you typically should check-in a manifest and CI should `instantiate` instead of `resolve`.
- For non-app packages it’s complicated:
  - If they are currently only used from within one repo, I think using a monorepo and a workspace is the cleanest solution, so they are covered by the manifest with `instantiate`, too.
  - If this is not possible and they are in their own repo, you can still decide to get a manifest from somewhere and use that.
  - If you also don’t want to do this, you actually need to `resolve` and be aware that CI is now no longer reproducible, meaning the success of a CI run depends both on your CI setup (including your repo) and on the dependencies, meaning you can have a totally random looking pass-fail pattern between your runs, because it is determined by changes in your (direct and indirect) dependencies.

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [July 29, 2026, 3:21am UTC](https://discourse.julialang.org/t/does-resolve-respect-julia-pkg-preserve-tiered-installed/138389/7 "2026-07-29T03:21:00Z")

</div>

> [@PatrickHaecker](#):
>
> I think using `resolve` on CI is at least problematic and it helps to think about the implications.

Sure, and I hate it for my use case.  
But there is no other option til [equivalent of Manifest.toml / pixi.lock · Issue #78 · JuliaPy/pyjuliapkg · GitHub](https://github.com/JuliaPy/pyjuliapkg/issues/78) is resolved

> Have you considered using [stacked environments](https://docs.julialang.org/en/v1.14-dev/manual/code-loading/#Environments) together with a temporary environment? As far as I know they only work in REPL-only workflows, but I guess this is the typical workflow for a temporary environment anyway.

They actually work everywhere. As far as they work at all.

They are a pretty dodgy feature that that does not actually play nicely at all with anything in Pkg.  
They ignore compat bounds conflicts between layers.  
And they violate the principle that your Manifest.toml should describe your dependancies.

But they are pretty useful so we still have them.  
But thankfully almost noone uses them outside the case of the per-minor version global enviroment.
