Kishu is a system for intelligent versioning of notebook session states on Jupyter-based platforms (e.g. JupyterLab, Jupyter Hub). Kishu efficiently creates checkpoints of both the variable and code states of a notebook session, allowing users to both undo cell executions and manage branching states containing objects such as machine learning models, plots, and dataframes through a Git-like commit and checkout interface.
Kishu can be installed from PyPI:
pip install kishu jupyterlab_kishu
Note: installing jupyterlab_kishu
will also install jupyterlab
into your environment.
Once Kishu has been installed, an additional Kishu
tab should appear in JupyterLab's toolbar. This tab will allow access to Kishu's various functionalities:
To start protecting your notebook session, Kishu can be initialized and attached through the Kishu > Initialize/Re-attach
option under the Kishu
tab. Alternatively, you can use the shortcut Ctrl+K then Ctrl+I
/ β+K then β+I
:
Once initialized, you can proceed to execute cells in the session as normal. Kishu will automatically and transparently checkpoint your variable state (imported libraries, loaded dataframes, drawn plots, fitted models, etc.) after each cell execution.
To undo your latest cell execution, you can use the Kishu > Undo Execution
option under the Kishu
tab:
Undoing cell executions only affects the variable state. The code state (i.e., the cells you write) is untouched. This can be useful, for example, to 'un-drop' a dataframe column dropped by a cell while keeping the cell code itself intact.
Kishu can also be used to manage branching code and variable states; it supports making checkpoints of the notebook and variable state at any point during a notebook session, which can be returned to later via a checkout.
Kishu can store the current state of your notebook, including both the variable state and your code state, with the Kishu > Commit
option under the Kishu
tab. Alternatively, you can use the shortcut Ctrl+K then Ctrl+C
/ β+K then β+C
. You will be prompted to enter a commit message:
You can return to a commit with the Kishu > Checkout
option under the Kishu
tab. Alternatively, you can use the shortcut Ctrl+K then Ctrl+V
/ β+K then β+V
. This will bring up a menu for you to select the appropriate commit:
Checking out will replace both the current variable and code state with that of the selected checkpoint. It will also overwrite your current variable and code state; commit to make a (second) checkpoint before checking out if you wish to keep your current notebook state.
Kishu can be configured through editing the ~/.kishu/config.ini
file. A full list of configurable options can be found here.
Optionally, you can install Kishuboard. Kishuboard is a graphical extension for Kishu. With the interactive GUI provided by KishuBoard, you can browse, compare and search commits, checkout code/kernel variables to previous commits; branch out etc in a straightforward way. For a full list of supported features and dev instructions for Kishuboard can be found here.
To install Kishuboard, run:
pip install kishuboard
And then, launch it with:
kishuboard
Now you should be able to visit it at localhost://4999
.
When Kishu is attached to a new notebook, refresh the notebook list. To enter the GUI of a specific notebook, simply click on its entry in the list.
This is the current list of libraries, their versions, and their classes supported by Kishu:
- β
: supported: All changes to instances of this class are always captured.
- π¨ : too conservative: Kishu may report changes on non-changes to instances of this class, i.e., false positives.
- β : failing: Some changes to an instance of this class may not be captured.
β
arrow==1.3.0, arrow.arrow.Arrow
β
astropy==5.2.2, astropy.convolution.Box2DKernel
β
astropy==5.2.2, astropy.convolution.Gaussian2DKernel
β
astropy==5.2.2, astropy.io.fits.HDUList
β
astropy==5.2.2, astropy.io.fits.PrimaryHDU
β
astropy==5.2.2, astropy.modeling.fitting.LinearLSQFitter
β
astropy==5.2.2, astropy.modeling.functional_models.Ellipse2D
β
astropy==5.2.2, astropy.modeling.functional_models.Linear1D
β
astropy==5.2.2, astropy.modeling.polynomial.Polynomial1D
β
astropy==5.2.2, astropy.modeling.polynomial.Polynomial2D
β
astropy==5.2.2, astropy.nddata.NDData
β
astropy==5.2.2, astropy.nddata.NDDataRef
β
astropy==5.2.2, astropy.stats.SigmaClip
β
astropy==5.2.2, astropy.table.QTable
β
astropy==5.2.2, astropy.units.Quantity
β
astropy==5.2.2, astropy.visualization.PercentileInterval
β
astropy==5.2.2, astropy.wcs.WCS
β
bokeh==2.4.3, bokeh.plotting._figure.figure
β
catboost==1.2.3, catboost
β
dask==2023.5.0, dask
β
dataprep==0.4.5, dataprep.datasets
β
dataprep==0.4.5, dataprep.eda.intermediate.Intermediate
β
dill==0.3.8, dill
β
gensim==4.3.2, gensim
β
gym==0.26.2, gym
β
ipywidgets==7.8.5, ipywidgets
β
keras==2.13.1, keras.src.initializers.initializers.RandomNormal
β
keras==2.13.1, keras.src.initializers.initializers.RandomUniform
β
keras==2.13.1, keras.src.layers.core.dense.Dense
β
keras==2.13.1, keras.src.optimizers.schedules.learning_rate_schedule.ExponentialDecay
β
lightgbm==4.3.0, lightgbm.basic.Dataset
β
llm==0.13.1, llm.default_plugins.openai_models.Chat
β
lmfit==1.2.2, lmfit.parameter.Parameters
β
matplotlib==3.7.5, matplotlib.colors.ListedColormap
β
matplotlib==3.7.5, matplotlib.dates.AutoDateFormatter
β
matplotlib==3.7.5, matplotlib.dates.WeekdayLocator
β
matplotlib==3.7.5, matplotlib.ticker.AutoLocator
β
networkx==3.1, networkx.classes.digraph.DiGraph
β
networkx==3.1, networkx.classes.graph.Graph
β
nltk==3.8.1, nltk.stem.porter.PorterStemmer
β
numpy==1.24.3, ast
β
numpy==1.24.3, copy
β
numpy==1.24.3, datetime.time
β
numpy==1.24.3, datetime.timedelta
β
numpy==1.24.3, hashlib
β
numpy==1.24.3, itertools
β
numpy==1.24.3, json
β
numpy==1.24.3, numpy.ndarray
β
numpy==1.24.3, numpy.ndarray
β
numpy==1.24.3, pickle
β
numpy==1.24.3, random.Random
β
numpy==1.24.3, re.Pattern
β
numpy==1.24.3, urllib.request.Request
β
numpy==1.24.3, uuid.UUID
β
opencv-python==4.9.0.80, cv2
β
optuna==3.5.0, optuna.Study
β
pandas==1.5.3, pandas.DataFrame
β
pandas==1.5.3, pandas.Series
β
pathlib==1.0.1, pathlib.PosixPath
β
photoutils==0.0.1, photutils.psf.matching.CosineBellWindow
β
photoutils==0.0.1, photutils.psf.matching.HanningWindow
β
photoutils==0.0.1, photutils.utils.CutoutImage
β
photoutils==0.0.1, photutils.utils.ImageDepth
β
plotly==5.18.0, plotly.express
β
plotly==5.18.0, plotly.figure_factory
β
plotly==5.18.0, plotly.graph_objects
β
plotly==5.18.0, plotly.graph_objs
β
plotly==5.18.0, plotly.io
β
plotly==5.18.0, plotly.offline
β
plotly==5.18.0, plotly.subplots
β
polars==0.14.29, polars.DataFrame
β
prophet==1.1.5, prophet.Prophet
β
pyspark==3.5.1, pyspark.sql
β
qiskit==0.45.0, qiskit.QuantumCircuit
β
scikit-image==0.21.0, skimage
β
scikit-image==0.21.0, skimage.morphology
β
scikit-learn==1.3.2, sklearn.cluster
β
scikit-learn==1.3.2, sklearn.cluster
β
scikit-learn==1.3.2, sklearn.compose
β
scikit-learn==1.3.2, sklearn.datasets
β
scikit-learn==1.3.2, sklearn.datasets
β
scikit-learn==1.3.2, sklearn.decomposition
β
scikit-learn==1.3.2, sklearn.discriminant_analysis
β
scikit-learn==1.3.2, sklearn.dummy
β
scikit-learn==1.3.2, sklearn.ensemble
β
scikit-learn==1.3.2, sklearn.feature_extraction.text
β
scikit-learn==1.3.2, sklearn.feature_selection
β
scikit-learn==1.3.2, sklearn.impute
β
scikit-learn==1.3.2, sklearn.impute
β
scikit-learn==1.3.2, sklearn.impute
β
scikit-learn==1.3.2, sklearn.kernel_ridge
β
scikit-learn==1.3.2, sklearn.linear_model
β
scikit-learn==1.3.2, sklearn.linear_model
β
scikit-learn==1.3.2, sklearn.manifold
β
scikit-learn==1.3.2, sklearn.metrics
β
scikit-learn==1.3.2, sklearn.metrics.pairwise
β
scikit-learn==1.3.2, sklearn.mixture
β
scikit-learn==1.3.2, sklearn.model_selection
β
scikit-learn==1.3.2, sklearn.multiclass
β
scikit-learn==1.3.2, sklearn.naive_bayes
β
scikit-learn==1.3.2, sklearn.neighbors
β
scikit-learn==1.3.2, sklearn.neural_network
β
scikit-learn==1.3.2, sklearn.pipeline
β
scikit-learn==1.3.2, sklearn.preprocessing
β
scikit-learn==1.3.2, sklearn.random_projection
β
scikit-learn==1.3.2, sklearn.svm
β
scikit-learn==1.3.2, sklearn.tree
β
scikit-learn==1.3.2, sklearn.utils
β
scipy==1.10.1, scipy.interpolate
β
scipy==1.10.1, scipy.ndimage
β
scipy==1.10.1, scipy.ndimage.interpolate
β
scipy==1.10.1, scipy.optimize
β
scipy==1.10.1, scipy.signal
β
scipy==1.10.1, scipy.signal.windows
β
scipy==1.10.1, scipy.sparse
β
scipy==1.10.1, scipy.spatial
β
scipy==1.10.1, scipy.spatial
β
scipy==1.10.1, scipy.spatial.distance
β
scipy==1.10.1, scipy.spatial.distance._hausdorff
β
scipy==1.10.1, scipy.special
β
scipy==1.10.1, scipy.stats
β
statsmodels==0.14.1, statsmodels.api
β
tensorflow==2.13.1, tensorflow
β
tensorflow==2.13.1, tensorflow.keras.models
β
tensorflow==2.13.1, tensorflow.keras.optimizers
β
textblob==0.17.1, textblob.TextBlob
β
torch==2.4.1, torch
β
torch==2.4.1, torch.nn
β
torch==2.4.1, torch.nn.functional
β
torch==2.4.1, torch.utils.data
β
transformers==4.38.2, huggingface
β
transformers==4.38.2, transformers
β
typing==3.7.4.3, typing
β
wordcloud==1.9.3, wordcloud.WordCloud
π¨ matplotlib==3.7.5, matplotlib.Axes
π¨ matplotlib==3.7.5, matplotlib.Axes
π¨ seaborn==0.13.0, seaborn
π¨ torch==2.4.1, torch.optim
π¨ polars==0.14.29, polars.LazyFrame
π¨ matplotlib==3.7.5, matplotlib.colors.BoundaryNorm
π¨ matplotlib==3.7.5, matplotlib.lines.Line2D
π¨ matplotlib==3.7.5, matplotlib.patches.Ellipse
π¨ matplotlib==3.7.5, matplotlib.patches.Arrow
π¨ matplotlib==3.7.5, matplotlib.image.AxesImage
π¨ matplotlib==3.7.5, matplotlib.image.FigureImage
π¨ matplotlib==3.7.5, matplotlib.offsetbox.AnchoredOffsetbox
π¨ astropy==5.2.2, astropy.visualization.mpl_normalize.ImageNormalize
π¨ astropy==5.2.2, astropy.wcs.Celprm
π¨ matplotlib==3.7.5, 'mpl_toolkits.mplot3d.art3d.Line3DCollection
Kishu may fail to correctly checkpoint notebook sessions containing the following items:
Kishu relies on the assumption that any object, when pickled then unpickled, is identical to the original object, and does not automatically detect cases where this assumption is violated (i.e., silent pickling errors). This is typically caused by errors in the object class' reduce function which acts as its pickling instructions; for example, an object with the below reduction (incorrectly) returns an empty (byte)string when pickled.
def __reduce__(self):
return ""
As a potential workaround, you can add object classes with incorrect reductions to a blocklist in Kishu's config to inform it to never try to store (and always recompute) objects belonging to these classes.
Kishu relies on cell replay to reconstruct unpicklable objects (e.g., generators). However, if the unpicklable object itself is created through non-deterministic means, Kishu will fail to exactly recreate it on undo/checkout, for example (assuming the seed for random
was not set):
nondet_gen = (i for i in range(random.randint(5, 10)))
Q1: I am getting a Kernel for the notebook not found
error when initializing Kishu on a new notebook file. What is going on?
A1: This happens if there is no running kernel for the current notebook file. Click the Kernel
icon to start a new notebook kernel, then proceed with initializing Kishu normally.
Kishu's efficiency is enabled by its low-overhead session state monitoring, deduplicated variable storage, and optimized recomputation-assisted checkout. Our papers on Kishu can be found here; don't forget to star our repository and cite our papers if you like our work!
- Kishu: Time-Traveling for Computational Notebooks
- Enhancing Computational Notebooks with Code+Data Space Versioning
- ElasticNotebook: Enabling Live Migration for Computational Notebooks
- Large-scale Evaluation of Notebook Checkpointing with AI Agents
- Transactional Python for Durable Machine Learning: Vision, Challenges, and Feasibility
- Demonstration of ElasticNotebook: Migrating Live Computational Notebook States
@article{li2024kishu,
title={Kishu: Time-Traveling for Computational Notebooks},
author={Li, Zhaoheng and Chockchowwat, Supawit and Sahu, Ribhav and Sheth, Areet and Park, Yongjoo},
journal={Proceedings of the VLDB Endowment},
volume={18},
number={4},
pages={970 - 985},
year={2024},
doi={10.14778/3717755.3717759},
publisher={VLDB Endowment},
}
@inproceedings{fang2025enhancing,
title={Enhancing Computational Notebooks with Code+Data Space Versioning},
author={Fang, Hanxi and Chockchowwat, Supawit and Sundaram, Hari and Park, Yongjoo},
booktitle={CHI Conference on Human Factors in Computing Systems (Chi '25)},
year={2025},
doi={doi.org/10.1145/3706598.3714141}
}
@article{li2023elasticnotebook,
title={ElasticNotebook: Enabling Live Migration for Computational Notebooks},
author={Li, Zhaoheng and Gor, Pranav and Prabhu, Rahul and Yu, Hui and Mao, Yuzhou and Park, Yongjoo},
journal={Proceedings of the VLDB Endowment},
volume={17},
number={2},
pages={119--133},
year={2023},
doi={10.14778/3626292.3626296},
publisher={VLDB Endowment}
}
@inproceedings{fang2025large,
title={Large-scale Evaluation of Notebook Checkpointing with AI Agents},
author={Fang, Hanxi and Chockchowwat, Supawit and Sundaram, Hari and Park, Yongjoo},
booktitle={Late-breaking work in CHI Conference on Human Factors in Computing Systems (Chi '25)},
year={2025}
}
@inproceedings{chockchowwat2023transactional,
title={Transactional python for durable machine learning: Vision, challenges, and feasibility},
author={Chockchowwat, Supawit and Li, Zhaoheng and Park, Yongjoo},
booktitle={Proceedings of the Seventh Workshop on Data Management for End-to-End Machine Learning},
pages={1--5},
year={2023},
doi={10.1145/3595360.3595855}
}
@inproceedings{li2024demonstration,
title={Demonstration of ElasticNotebook: Migrating Live Computational Notebook States},
author={Li, Zhaoheng and Chockchowwat, Supawit and Fang, Hanxi and Sahu, Ribhav and Thakurdesai, Sumay and Pridaphatrakun, Kantanat and Park, Yongjoo},
booktitle={Companion of the 2024 International Conference on Management of Data},
pages={540--543},
year={2024},
doi={10.1145/3626246.3654752}
}
To get started with developing Kishu, see CONTRIBUTING.md.