Migrate data
opik migrate moves an entity — and everything attached to it — from one project to another in the same workspace. It copies the entity’s full version history and its related data into the destination project.
It has two subcommands:
opik migrate dataset— a dataset (or test suite) with its full version history, plus the experiments, traces, spans, feedback scores, assertion results, comments, and optimizations attached to it.opik migrate prompt— a prompt and its full version history.
Use it to consolidate or re-home an entity and its history under a different project.
These commands move data between projects in a single workspace. To move data between
separate Opik installations or environments, use opik export / opik import instead.
The migration renames the source to <name>_v1 and gives the destination the original
name. Preview with --dry-run first to see exactly what will change.
Options
The --workspace and --api-key flags go on the opik migrate group, before the subcommand. The rest are shared by both dataset and prompt.
Previewing a migration
Add --dry-run to any migration to see exactly what it would do without changing anything — nothing is renamed and nothing is copied. The command resolves the source, prints the plan it would run step by step, then exits.
Use the preview to confirm the source resolved to the right entity and that the destination project is correct. When the plan looks right, run the same command again without --dry-run to apply it.
opik migrate dataset
NAME is the exact name of the source dataset. Both plain datasets and test suites are supported. Preview with --dry-run before applying.
What gets copied
What happens when you run it
The same steps appear in the --dry-run plan:
What is not copied
- Prompt snapshots on experiments — migrate prompts separately with
opik migrate prompt. - Attachments on traces and spans — files like images and audio are not copied.
- Thread tags, status, feedback scores, and comments — the traces themselves (including their environment) do come across, but these thread-level fields don’t yet.
Examples
Resuming an interrupted migration
If a migration is interrupted — a crash, a dropped connection, or the process being killed (for example, out-of-memory on a very large dataset) — just re-run the exact same command from the same machine. It resumes instead of starting over:
- Already-migrated experiments are skipped. Progress is checkpointed after each experiment completes, so a re-run picks up from the last completed one. The progress bar reflects this — a migration that was ~53% done resumes near 53%, not 0%.
- An experiment interrupted mid-flight is re-migrated cleanly. Its partial traces, spans, and experiment record at the destination are deleted first, so the re-run doesn’t leave duplicates behind.
The checkpoint is stored locally under ~/.opik/migrate-checkpoints/, keyed by workspace + destination project + dataset name, so a re-run resumes regardless of which directory you run it from. It is removed automatically once the migration finishes successfully. Resume is local to the machine that ran the migration — moving to a different machine starts fresh. (Experiments are the checkpoint granularity; there is no finer per-trace or per-span resume.)
opik migrate prompt
NAME is the exact name of the source prompt. This subcommand migrates the prompt and its version history only — it does not copy experiments, traces, or spans. Preview with --dry-run before applying.
What gets copied
- Prompt — name, description, tags, and template structure.
- Version history — every version, oldest first, with its template, metadata, type, change description, and tags.
- Commit hashes — each version’s commit hash is preserved, so the history matches the source exactly.
It renames the source to <name>_v1, creates the destination prompt under --to-project, and replays every version.
Examples
Troubleshooting
-
Name already used — the rename target
<name>_v1already exists. Rename or delete the conflicting entity and re-run: