Caching¶
marimo comes with utilities to cache intermediate computations. These utilities come in two types: caching the return values of expensive functions in memory, and caching the values of variables to disk.
Caching expensive functions¶
Use mo.cache
to cache the return values of functions in
memory, based on the function arguments, closed-over values, and the notebook
code defining the function.
The resulting cache is similar to functools.cache
, but with the benefit that
mo.cache
won't return stale values (because it keys on
closed-over values) and isn't invalidated when the cell defining the decorated
function is simply re-run (because it keys on notebook code). This means that
like marimo notebooks, mo.cache
has no hidden state
associated with the cached function, which makes you more productive while developing iteratively.
For a cache with bounded size, use mo.lru_cache
.
marimo.cache
¶
cache(
name: Union[str, Optional[Callable[..., Any]]] = None,
*args: Any,
loader: Optional[Union[LoaderPartial, Loader]] = None,
_frame_offset: int = 1,
**kwargs: Any
) -> Union[_cache_call, _cache_context]
Cache the value of a function based on args and closed-over variables.
Decorating a function with @mo.cache
will cache its value based on
the function's arguments, closed-over values, and the notebook code.
Usage.
mo.cache
is similar to functools.cache
, but with three key benefits:
mo.cache
persists its cache even if the cell defining the cached function is re-run, as long as the code defining the function (excluding comments and formatting) has not changed.mo.cache
keys on closed-over values in addition to function arguments, preventing accumulation of hidden state associated withfunctools.cache
.mo.cache
does not require its arguments to be hashable (only pickleable), meaning it can work with lists, sets, NumPy arrays, PyTorch tensors, and more.
mo.cache
obtains these benefits at the cost of slightly higher overhead
than functools.cache
, so it is best used for expensive functions.
Like functools.cache
, mo.cache
is thread-safe.
The cache has an unlimited maximum size. To limit the cache size, use
@mo.lru_cache
. mo.cache
is slightly faster than mo.lru_cache
, but in
most applications the difference is negligible.
Note, mo.cache
can also be used as a drop in replacement for context block
caching like mo.persistent_cache
.
Args:
pin_modules
: if True, the cache will be invalidated if module versions differ.
marimo.lru_cache
¶
lru_cache(
name: Union[str, Optional[Callable[..., Any]]] = None,
maxsize: int = 128,
*args: Any,
**kwargs: Any
) -> Union[_cache_call, _cache_context]
Decorator for LRU caching the return value of a function.
mo.lru_cache
is a version of mo.cache
with a bounded cache size. As an
LRU (Least Recently Used) cache, only the last used maxsize
values are
retained, with the oldest values being discarded. For more information,
see the documentation of mo.cache
.
Usage.
Caching variables to disk¶
Use mo.persistent_cache
to cache variables computed in an expensive block of
code to disk. The next time this block of code is run, if marimo detects a
cache hit, the code will be skipped and your variables will be loaded into
memory, letting you pick up where you left off.
Cache location
By default, caches are stored in __marimo__/cache/
, in the directory of the
current notebook. For projects versioned with git
, consider adding
**/__marimo__/cache/
to your .gitignore
.
marimo.persistent_cache
¶
persistent_cache(
name: Union[str, Optional[Callable[..., Any]]] = None,
save_path: str | None = None,
*args: Any,
**kwargs: Any
) -> Union[_cache_call, _cache_context]
Cache interface to persistently pickle values and load them depending on notebook state.
Can be used as a context manager or a decorator. Mainly expected to be used
as a decorator due to expensive overhead. Refer to mo.cache
for equivalent
functionality on how to use as this as a decorator.