# Save/load REPL state

**URL:** <https://discourse.julialang.org/t/save-load-repl-state/102433>\
**Category:** General Usage\
**Created:** [August 3, 2023, 4:07am UTC](https://discourse.julialang.org/t/save-load-repl-state/102433 "2023-08-03T04:07:06Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tarny\_GG\_Channie](https://avatars.discourse-cdn.com/v4/letter/t/3bc359/32.png) [@Tarny\_GG\_Channie](https://discourse.julialang.org/u/Tarny_GG_Channie)\
**Post date:** [August 3, 2023, 4:07am UTC](https://discourse.julialang.org/t/save-load-repl-state/102433/1 "2023-08-03T04:07:06Z")

</div>

Julia has a strong point in being JIT-compiled language that incremental compilation works (it has to). Still, to take full advantage of that, saving state is required.  
Imagine you have a codebase which takes 20 minutes to compile, then the part you want to fix. Ideally, you would run the code for 20 minutes, save the state, then just re-load the REPL state several times to test the new part.  
How would you do that in practice?

---

<div class="post-metadata">

**Author:** ![albheim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albheim/32/34660_2.png) [@albheim](https://discourse.julialang.org/u/albheim)\
**Post date:** [August 3, 2023, 6:17am UTC](https://discourse.julialang.org/t/save-load-repl-state/102433/2 "2023-08-03T06:17:02Z")

</div>

What does “the part you want to fix” consist of? Can it not just be redefined in the running session? Maybe Revise.jl can make the workflow more convenient?

Or if the “codebase that takes 20 minutes to compile” is only about precompilation, maybe put that code in a package and put some good precompile instructions for it, then loading it should be fast in 1.9+?

With that said, a way to save the state could probably be convenient in many cases. Though I have no clue how hard it would be to implement, and I’m pretty sure it doesn’t currently exist.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [August 3, 2023, 7:13am UTC](https://discourse.julialang.org/t/save-load-repl-state/102433/3 "2023-08-03T07:13:32Z")

</div>

It also depends what you mean by saving the REPL state:

- If you mean precompiled code, the easiest way is to use [GitHub - JuliaLang/PrecompileTools.jl: Reduce time-to-first-execution of Julia code](https://github.com/JuliaLang/PrecompileTools.jl) in your package.
- If you mean actual REPL results, you might want to enable the numbered prompt introduced in Julia 1.9

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [August 3, 2023, 7:50am UTC](https://discourse.julialang.org/t/save-load-repl-state/102433/4 "2023-08-03T07:50:33Z")

</div>

[Old thread](https://discourse.julialang.org/t/what-is-harder-about-saving-a-julia-session-via-the-repl-whenever/82897) of mine on this topic.

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [August 3, 2023, 9:06am UTC](https://discourse.julialang.org/t/save-load-repl-state/102433/5 "2023-08-03T09:06:39Z")

</div>

Thanks for the link. Interesting read!

Since that conversation happened, 1.9 introduced changing the active module in the REPL. I wonder if this mitigates @anon56330260’s point that you can’t serialize Main because it is in constant flux.

A user could start by dropping into `Main.Workspace`, import packages, define some functions, run a long-running process that constructs a DataFrame of results and assign it to `df`, then jump back up to Main and serialize `Main.Workspace` and exit the REPL.

When they open the REPL to work the next day, they deserialize `Main.Workspace` and get all of their functions and `df` back and don’t need to start from scratch.

This is a feature that R supports. You can save all the variables defined in the current session so you can come back tomorrow without rerunning your script. It should be awesome if, when I open a Pluto notebook, it was just ready for me to code instead of running the whole thing from the top again, potentially running very expensive computations.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [August 3, 2023, 12:11pm UTC](https://discourse.julialang.org/t/save-load-repl-state/102433/6 "2023-08-03T12:11:44Z")

</div>

> [@albheim](#):
>
> With that said, a way to save the state could probably be convenient in many cases. Though I have no clue how hard it would be to implement, and I’m pretty sure it doesn’t currently exist.

See also [Checkpointing with Julia](https://discourse.julialang.org/t/checkpointing-with-julia/24026)

---

<div class="post-metadata">

**Author:** ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)\
**Post date:** [August 3, 2023, 10:29pm UTC](https://discourse.julialang.org/t/save-load-repl-state/102433/7 "2023-08-03T22:29:41Z")

</div>

That thread was carried under the context of serialization. My point concerned about whether it’s possible to serialize Main in a stable, automatic and safe way, with a focus on compilation latency. Notice that these two concepts (compilation latency and serialization) are largely orthogonal. You can serialize julia values without saving binary codes, vice versa.

I think my conclusion is still no. Workspace is simply a module without package organization. They are constructed by toplevel `include` instead of `import`/`using`. The mechanism is still the same as precompiled module. Programmers are required to take care of non-serializable values (handlers/Task) and prevent them from saving, manually. This is exact what I am talking about in that thread (`it just works as long as you don’t do strange thing`):

> [@What is harder about saving a Julia session via the REPL whenever?](https://discourse.julialang.org/t/what-is-harder-about-saving-a-julia-session-via-the-repl-whenever/82897/10):
>
> So I guess what you want is like this:
> 
> 1. Execute some Julia codes in REPL, which is some function calls to other libraries, for example, `Plots.plot`.
> 2. The compiled binary codes and other necessary serializable runtime metadata are cached.
> 3. The next time you open REPL, you re-execute you script to set up those runtime you don’t want to cache, and then these compiled codes are loaded. You don’t need to recompile them, so a lot of time is saved.
> 
> If this is what you want, then it can be achieved (as long as you don’t save the global and definitions, you can always reexecute them for they take less time compared to compilation). I have a private fork of Julia’s compiler for this kind of binary cache, which utilizes LLVM’s new linking architecture. It indeed works much like what you just said in this thread. And it has all the limitations I mentioned above, it just works as long as you don’t do strange things.

If you are interested, you can actually read my slides `Build System` on this topic, especially slide 14-15. [https://docs.google.com/presentation/d/1wTP\_nnQYiRLHYnrItrUnYsp7zX7q4vWMmhpONd8Ne\_s/edit?usp=sharing](https://docs.google.com/presentation/d/1wTP_nnQYiRLHYnrItrUnYsp7zX7q4vWMmhpONd8Ne_s/edit?usp=sharing) I talk about this problem in depth.

---

<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:** [August 3, 2023, 11:35pm UTC](https://discourse.julialang.org/t/save-load-repl-state/102433/8 "2023-08-03T23:35:55Z")

</div>

> [@mrufsvold](#):
>
> This is a feature that R supports. You can save all the variables defined in the current session so you can come back tomorrow without rerunning your script. It should be awesome if, when I open a Pluto notebook, it was just ready for me to code instead of running the whole thing from the top again, potentially running very expensive computations.

A major difference is that R retains their functions in source code form, while Julia does not. While you might be able to recursively serialize the data structures in the current workspace, serializing JIT compiled functions does not make sense. JIT compiled code contains optimizations relevant only to JIT such as runtime pointer references which would be invalid when deserialized.

To get serializable native code, you help to get Julia into an mode where it is caching native code to disk. See `julia --help-hidden` for options.

```julia
 --compile={yes*|no|all|min}
                          Enable or disable JIT compiler, or request exhaustive or minimal compilation

 --output-o <name> Generate an object file (including system image data)
 --output-ji <name> Generate a system image data file (.ji)
 --strip-metadata Remove docstrings and source location info from system image
 --strip-ir Remove IR (intermediate representation) of compiled functions

 --output-unopt-bc <name> Generate unoptimized LLVM bitcode (.bc)
 --output-bc <name> Generate LLVM bitcode (.bc)
 --output-asm <name> Generate an assembly file (.s)
 --output-incremental={yes|no*}
                          Generate an incremental output file (rather than complete)
 --trace-compile={stderr,name}
                          Print precompile statements for methods compiled during execution or save to a path
 --image-codegen Force generate code in imaging mode

```

---

<div class="post-metadata">

**Author:** ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)\
**Post date:** [August 4, 2023, 12:25am UTC](https://discourse.julialang.org/t/save-load-repl-state/102433/9 "2023-08-04T00:25:09Z")

</div>

Technically R and Matlab can’t save arbitrary values. The same limitations apply to all languages.

> [@mkitti](#):
>
> While you might be able to recursively serialize the data structures in the current workspace, serializing JIT compiled functions does not make sense.

You can actually do this by recursively caching all the functions and all the data that the functions referring to. Most of the time, this simply dumps everything in the enviorment. Note that to cache a data structure you must cache its type, but every type in Julia is a pointer already. You have such an impression because of the current way Julia implements it’s JIT compiler. But replacing pointer by mangled symbol name is totally possible.

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

I believe the main difference here is that in those languages interactive users seldom define their own types and functions. So many users never notice such things.

---

<div class="post-metadata">

**Author:** ![pxshen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pxshen/32/38776_2.png) [@pxshen](https://discourse.julialang.org/u/pxshen)\
**Post date:** [July 22, 2024, 7:51pm UTC](https://discourse.julialang.org/t/save-load-repl-state/102433/10 "2024-07-22T19:51:09Z")

</div>

What about linux “hibernation” tools like `criu` that dumps memory to disk to restore entire processes?
