Migrating to Opik 2.0
Opik 2.0 organizes everything around projects. Data created after upgrading is automatically project-scoped. Data created on Opik 1.x — datasets, prompts, experiments, optimizations, automation rules, and alerts — requires six background jobs to assign each item to the right project. This page walks you through running those jobs.
Upgrading from Opik 1.x with existing data? Recent Opik images default TOGGLE_FORCE_WORKSPACE_VERSION to version_2, which loads the Opik 2.0 UI globally regardless of your existing entities. 1.x entities that have not yet been assigned to a project (no project_id) will not be visible in the 2.0 UI until you run the migration jobs below.
Before you start
- Update to the latest Opik image. All six migration jobs ship with the 2.0 release. Make sure your
opik-backendis running the 2.0 image before enabling any flag. - Take a database snapshot. Each job writes to MySQL or ClickHouse. Back up both before starting — see Advanced ClickHouse backup for ClickHouse, and use
mysqldumpor your RDS snapshot tooling for MySQL. - Confirm your deployment is healthy. The
opik-backendcontainer should be running with no restart loops, and MySQL and ClickHouse should be at baseline load.
How the jobs work
Each job runs inside opik-backend on a 30-second cycle. They are:
- Safe to run alongside live traffic — no user-visible locks; users can keep working throughout.
- Resumable — stopping a job mid-run and re-enabling it picks up where it left off.
- Stoppable, not undoable — already-committed writes stay; there is no rollback mode.
When an item’s associated data spans multiple projects, it is assigned to the dominant project — the one most referenced by its runs. When no project can be determined at all (no associated runs, or the original project was deleted), it falls back to the workspace’s Default Project, which is created on demand if missing.
Order of execution
Run the jobs in the order below. Datasets, prompts, and optimizations infer their project from
experiments.project_id. Starting them before the experiment job finishes silently routes those
items to Default Project with no retry — they are not re-evaluated once experiments land
their correct project later.
Step 1 — Experiments
Enable
Docker Compose
Kubernetes / Helm
Add to a docker-compose.override.yml in your deployment/docker-compose directory:
Apply:
Watch for completion
Docker Compose
Kubernetes / Helm
The job is done when this line appears consistently for several cycles:
Disable
Set EXPERIMENT_PROJECT_MIGRATION_ENABLED=false using the same method above and apply. Wait for the completion signal to be stable before moving to Step 2.
Step 2 — Datasets and prompts
Enable both once Step 1 is complete. They are independent of each other and can run in parallel.
Docker Compose
Kubernetes / Helm
Completion signals:
Disable each flag individually once its completion signal is stable before moving to Step 3.
Step 3 — Optimizations
Enable only after both Step 1 and Step 2 are complete. Optimizations infer their project from both experiments and datasets.
Docker Compose
Kubernetes / Helm
Completion signal:
Disable the flag once the signal is stable.
Step 4 — Automation rules and alerts
These jobs inspect project references already stored in their own rows and have no dependency on the other jobs. Run them at any point — before, during, or after Steps 1–3.
Docker Compose
Kubernetes / Helm
Completion signals:
Disable each flag once done.
Verifying the migration
Once all six jobs have reported their completion signals and been disabled, run these queries to confirm the result.
ClickHouse — orphan experiments (should be 0):
MySQL — orphan datasets (should be 0):
MySQL — orphan prompts (should be 0):
ClickHouse — orphan optimizations (should be 0):
MySQL — multi-project automation rules (should be 0):
MySQL — orphan alerts (should be 0):
Troubleshooting
Next steps
Once migration is complete, update your SDK and pass project_name on your API calls. See Upgrading to Opik 2.0 for the full code reference and examples.