Long studies crash, notebooks restart and teams want to look at results; persistence makes studies durable.
By default a study lives in memory and disappears with the process. Pass a storage to persist it:
study = optuna.create_study(study_name="rf-tuning", storage="sqlite:///optuna.db",
direction="maximize", load_if_exists=True)study_nameidentifies the study inside the storage.load_if_exists=Trueresumes an existing study instead of failing, so the same script can be re-run to add more trials.optuna.load_study(study_name=..., storage=...)opens a study for analysis elsewhere.
Storage options:
- RDB URLs (SQLite, PostgreSQL, MySQL) via SQLAlchemy. SQLite is fine for one machine; use PostgreSQL or MySQL for many concurrent workers.
- JournalStorage with
JournalFileBackend("journal.log"): an append-only log file, simple and robust for multiple processes on one machine or a shared filesystem, with no database server. JournalRedisBackendfor Redis.
Utilities: optuna.get_all_study_names(storage), optuna.delete_study, optuna.copy_study, and the optuna CLI (optuna studies --storage ...).
optuna-dashboard (pip install optuna-dashboard, then optuna-dashboard sqlite:///optuna.db) gives a live web UI with history, importances and parameter plots.
Trials interrupted by a crash stay RUNNING; enable heartbeats (RDBStorage(url, heartbeat_interval=60)) so they are marked failed and optionally retried.
Example
import optuna
optuna.logging.set_verbosity(optuna.logging.WARNING)
def objective(trial):
x = trial.suggest_float("x", -10, 10)
return (x - 3) ** 2
storage = "sqlite:///optuna_demo.db"
for session in range(2): # e.g. two separate script runs
study = optuna.create_study(study_name="quadratic", storage=storage,
load_if_exists=True)
study.optimize(objective, n_trials=10)
print(f"session {session}: {len(study.trials)} trials")
# session 0: 10 trials
# session 1: 20 trials (resumed)
loaded = optuna.load_study(study_name="quadratic", storage=storage)
print(round(loaded.best_params["x"], 1)) # near 3.0
optuna.delete_study(study_name="quadratic", storage=storage)
from optuna.storages import JournalStorage
from optuna.storages.journal import JournalFileBackend
journal = JournalStorage(JournalFileBackend("optuna_journal.log"))Remember
- Pass
storage=andstudy_name=to persist a study load_if_exists=Truelets the same script resume- SQLite or journal files for one machine; PostgreSQL/MySQL for many workers
Watch out for
- Pointing many parallel workers at one SQLite file, which leads to lock contention and errors.