priority_high

Important

This is an experimental feature. Experimental features and their APIs may change or be removed at any time. To learn more, click here.

Function decorator to memoize function executions.

Memoized data is stored in "pickled" form, which means that the return value of a memoized function must be pickleable.

Each caller of a memoized function gets its own copy of the cached data.

You can clear a memoized function's cache with f.clear().

Function signature

st.experimental_memo(func=None, *, persist=None, show_spinner=True, suppress_st_warning=False, max_entries=None, ttl=None)

Parameters

func (callable)

The function to memoize. Streamlit hashes the function's source code.

persist (str or None)

Optional location to persist cached data to. Currently, the only valid value is "disk", which will persist to the local disk.

show_spinner (boolean)

Enable the spinner. Default is True to show a spinner when there is a cache miss.

suppress_st_warning (boolean)

Suppress warnings about calling Streamlit functions from within the cached function.

max_entries (int or None)

The maximum number of entries to keep in the cache, or None for an unbounded cache. (When a new entry is added to a full cache, the oldest cached entry will be removed.) The default is None.

ttl (float or None)

The maximum number of seconds to keep an entry in the cache, or None if cache entries should not expire. The default is None. Note that ttl is incompatible with persist="disk" - ttl will be ignored if persist is specified.

Example

@st.experimental_memo
def fetch_and_clean_data(url):
    # Fetch data from URL here, and then clean it up.
    return data

d1 = fetch_and_clean_data(DATA_URL_1)
# Actually executes the function, since this is the first time it was
# encountered.

d2 = fetch_and_clean_data(DATA_URL_1)
# Does not execute the function. Instead, returns its previously computed
# value. This means that now the data in d1 is the same as in d2.

d3 = fetch_and_clean_data(DATA_URL_2)
# This is a different URL, so the function executes.

To set the persist parameter, use this command as follows:

@st.experimental_memo(persist="disk")
def fetch_and_clean_data(url):
    # Fetch data from URL here, and then clean it up.
    return data

By default, all parameters to a memoized function must be hashable. Any parameter whose name begins with _ will not be hashed. You can use this as an "escape hatch" for parameters that are not hashable:

@st.experimental_memo
def fetch_and_clean_data(_db_connection, num_rows):
    # Fetch data from _db_connection here, and then clean it up.
    return data

connection = make_database_connection()
d1 = fetch_and_clean_data(connection, num_rows=10)
# Actually executes the function, since this is the first time it was
# encountered.

another_connection = make_database_connection()
d2 = fetch_and_clean_data(another_connection, num_rows=10)
# Does not execute the function. Instead, returns its previously computed
# value - even though the _database_connection parameter was different
# in both calls.

A memoized function's cache can be procedurally cleared:

@st.experimental_memo
def fetch_and_clean_data(_db_connection, num_rows):
    # Fetch data from _db_connection here, and then clean it up.
    return data

fetch_and_clean_data.clear()
# Clear all cached entries for this function.

Persistent memo caches currently don't support TTL. ttl will be ignored if persist is specified:

import streamlit as st

@st.experimental_memo(ttl=60, persist="disk")
def load_data():
    return 42

st.write(load_data())

And a warning will be logged to your terminal:

$ streamlit run app.py

  You can now view your Streamlit app in your browser.
  Local URL: http://localhost:8501
  Network URL: http://192.168.1.1:8501

2022-09-22 13:35:41.587 The memoized function 'load_data' has a TTL that will be ignored. Persistent memo caches currently don't support TTL.

Functions decorated with @st.experimental_memo can contain static st elements. When a cache-decorated function is executed, we record the element and block messages produced, so the elements will appear in the app even when execution of the function is skipped because the result was cached.

In the example below, the @st.experimental_memo decorator is used to cache the execution of the load_data function, that returns a pandas DataFrame. Notice the cached function also contains a st.area_chart command, which will be replayed when the function is skipped because the result was cached.

import numpy as np
import pandas as pd
import streamlit as st

@st.experimental_memo
def load_data(rows):
    chart_data = pd.DataFrame(
        np.random.randn(rows, 10),
        columns=["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"],
    )
    # Contains a static element st.area_chart
    st.area_chart(chart_data) # This will be recorded and displayed even when the function is skipped
    return chart_data

df = load_data(20)
st.dataframe(df)

Supported static st elements in cache-decorated functions include:

  • st.alert
  • st.altair_chart
  • st.area_chart
  • st.bar_chart
  • st.ballons
  • st.bokeh_chart
  • st.caption
  • st.code
  • st.components.v1.html
  • st.components.v1.iframe
  • st.container
  • st.dataframe
  • st.echo
  • st.empty
  • st.error
  • st.exception
  • st.expander
  • st.experimental_get_query_params
  • st.experimental_set_query_params
  • st.graphviz_chart
  • st.help
  • st.info
  • st.json
  • st.latex
  • st.line_chart
  • st.markdown
  • st.metric
  • st.plotly_chart
  • st.progress
  • st.pydeck_chart
  • st.snow
  • st.spinner
  • st.success
  • st.table
  • st.text
  • st.vega_lite_chart
  • st.warning

All other st commands, including widgets, forms, and media elements are not supported in cache-decorated functions. If you use them, the code will only be called when we detect a cache "miss", which can lead to unexpected results. Which is why Streamlit will throw a CachedStFunctionWarning, like the one below:

import numpy as np
import pandas as pd
import streamlit as st

@st.experimental_memo
def load_data(rows):
    chart_data = pd.DataFrame(
        np.random.randn(rows, 10),
        columns=["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"],
    )
    # Contains an unsupported st command
    st.slider("Select a value", 0, 10, 5) # Streamlit will throw a CachedStFunctionWarning

    return chart_data

df = load_data(20)
st.dataframe(df)

Was this page helpful?

editSuggest edits
forum

Still have questions?

Our forums are full of helpful information and Streamlit experts.