Bulk Migrate a Codebase

Convert an entire directory of SQL files as a batch: analyze first, run with adaptive parallel workers, watch progress from the CLI or the web UI, then triage the result by confidence band instead of reading every file in order.

Overview

A bulk migration in 3xcode is a batch: a named group of SQL files converted together, tracked inside a session, with its own worker pool and report. The workflow below is the recommended path for a real migration; see Sessions & Batches if you haven't seen how workspaces, sessions, and batches relate yet.

1

Analyze

Preview dialect, platform, and object counts before spending on a full run.

2

Create & Run

Build the batch, seal its file list, and run it with adaptive workers.

3

Monitor & Triage

Watch live progress, then read the report and prioritize by confidence band.

Step 1: Analyze

Before committing a whole directory to a full run, get a cheap preview. A --dry-run executes only discovery and planning: detected dialect and platform, object inventory, complexity, and the dependency-ordered conversion plan, with no PySpark code generated yet.

Terminal
# Log in and confirm the machine is set up correctly
3xcode login
3xcode health

# Initialize a workspace for this migration
3xcode workspace init ./warehouse-migration --name "warehouse-migration"
cd warehouse-migration
# Copy your source SQL into ./input/, or point --dir at wherever it already lives

# Preview the batch before running it for real
3xcode pyspark convert --dir ./input/ --dry-run

3xcode health also reports your machine's CPU and RAM, useful context before a large run, though you rarely need to act on it directly since worker concurrency auto-tunes (see Step 3).

Step 2: Create a Batch

Create a session to hold the migration, then create a batch inside it and add your files. A batch stays open, you can keep adding files, until you seal it: sealing freezes the file list so a run always converts exactly what you intended.

Terminal
# Create a session for this migration
3xcode session create --name "warehouse-migration"
# -> prints the session ID, e.g. session-20260716-warehouse-migration

# Create a batch and add every .sql file in a directory
3xcode batch create <session_id> --name "phase-1" --dir ./input/ --sort simple-first
# -> prints the batch ID, e.g. batch-phase-1

# Freeze the file list once you're happy with what's included
3xcode batch seal <session_id> <batch_id>

# batch list shows every batch in the session and its state
3xcode batch list <session_id>

--sort controls the order files are attempted in: simple-first (the default) surfaces quick wins early, complex-first front-loads the hardest objects while the full worker pool is fresh. Prefer the quick, one-step shorthand instead? 3xcode pyspark convert --dir ./input/ --session "warehouse-migration" creates and runs an implicit batch in a single command, equivalent to Steps 2 and 3 combined.

Step 3: Run the Batch

batch run always runs as a detached background worker: it returns immediately, so closing your terminal doesn't stop the batch.

Terminal
3xcode batch run <session_id> <batch_id>

# Optionally cap how far parallelism is allowed to grow
3xcode batch run <session_id> <batch_id> --workers 8

-w is a ceiling, not a fixed count

Left at its default (0), the batch runner starts conservatively and ramps concurrency up as files keep succeeding, backing off automatically if the provider pushes back or memory gets tight. Passing -w N caps how high it's allowed to climb; it doesn't force exactly N workers.

Detached by design

A batch run is always a background worker. There's no foreground mode to babysit: move on to Step 4 to watch its progress instead.

Step 4: Monitor in the CLI and Web UI

Check on a running batch from the terminal, or open the web UI for a visual dashboard. Both read the same underlying state, so it doesn't matter which one you started the batch from.

batch watch

A live dashboard in your terminal: per-file progress, current phase, and a running tally. Omit the batch ID to watch every batch in a session at once.

3xcode ui

Batch cards on the Sessions page show a live confidence-distribution bar and done/failed counts at a glance; filter chips narrow the view by state or confidence band.

Terminal
# Live dashboard for this specific batch
3xcode batch watch <session_id> <batch_id>

# Or watch every batch in the session
3xcode batch watch <session_id>

# Prefer a browser?
3xcode ui

Step 5: Read the Report

Once a batch finishes, its output directory contains a BATCH_SUMMARY.md report: total files, completed and failed counts, a per-file table (status, confidence, completion, cost, duration), a confidence and completion band breakdown, a phase-cost rollup, and a Needs Attention section flagging anything worth a second look. Read this before opening individual files, it tells you where to look first.

Terminal
3xcode session info <session_id>
cat output/<session_id>/<batch_id>/BATCH_SUMMARY.md

Step 6: Triage by Confidence Band

Every successfully converted file lands in one of four confidence bands. Work through a large batch from the bottom up rather than in alphabetical or file order.

BandRangePriority
LowBelow 70Review first: real issues found, or constructs with no safe automatic fix
Medium70-89.99Review next: read the manual-review items before treating the file as done
High90-99.99Spot check: minor issues at most, likely already auto-fixed
Perfect100Still worth a glance, but the lowest-risk tier of the batch

See Billing & Quota for how bands are defined, and Batch Conversion & Sessions for the full report format.

Handling a Partial Run

If a batch is cancelled, loses network connectivity, or the machine goes down mid-run, already-completed files stay completed. Resume it and only the unfinished files are re-attempted, under the same success-only billing, a file already charged for a successful conversion is never billed again.

Terminal
3xcode batch list <session_id>
3xcode batch resume <session_id> <batch_id>

# If the pause window has expired, re-run it instead
3xcode batch run <session_id> <batch_id>

Troubleshooting

No workspace found

Batch conversion requires an active workspace. Run 3xcode workspace init <path> --name <name> first, or 3xcode workspace switch <path> if you already have one registered.

`batch run` refuses with "a runner is already live"

Only one worker can run a given batch at a time, to avoid converting (and billing) the same files twice. Check 3xcode batch watch <session_id> <batch_id> to see the run already in progress, or 3xcode batch cancel it first if it's stuck.

A batch hangs or shows no progress in `batch watch`

Confirm a worker is actually running with 3xcode batch list <session_id> (state should be running). If it's idle, resume it with 3xcode batch resume <session_id> <batch_id>.

Web UI shows "Not logged in" or starts 403-ing on every request

A browser tab left open across a 3xcode ui restart can serve a stale session cookie. Hard-refresh or reopen the UI tab so it picks up the fresh session minted on the new launch.

Can't delete a session or batch

Delete refuses to run while a worker is active. Run 3xcode batch cancel <session_id> <batch_id> first, then delete.