Sessions & Batches

The three levels 3xcode uses to organize a migration: a workspace holds sessions, a session groups batches, and a batch is where files actually get converted in parallel.

The Hierarchy

Every conversion, whether it's one file or a few thousand, is organized the same way. Understanding these three levels makes the rest of the CLI (and the web UI) click into place, since almost every command operates on one of them.

1

Workspace

A project folder: input/, output/, .sessions/, logs/. Everything below lives inside one.

2

Session

A container for a body of migration work in that workspace. A session can hold one batch or many.

3

Batch

A named group of SQL files converted together, with its own worker pool, schedule, and report.

4

Files

Each file in a batch runs the full conversion pipeline independently and lands in its own output.

Workspace

A workspace is the top-level project folder: 3xcode workspace init ./path --name "..." lays down input/, output/, .sessions/, and logs/, then sets it active. Everything you do afterward, single-file conversions, sessions, batches, happens inside whichever workspace is currently active. You can register several workspaces (one per migration, client, or environment) and switch between them with workspace switch.

Session

A session is a container for a piece of migration work. 3xcode session create starts one, and everything you do inside it (single-file conversions, or one or more batches) is tracked under that session's ID for status, resume, and reporting. session list shows every session in the active workspace; session list-all shows currently-running sessions across every registered workspace on the machine.

Core session commands

CommandWhat it does
session createStarts a new session, optionally pointed at a directory of SQL files
session list / session info <id>List sessions, or see a full per-file breakdown for one
session status <id> --watchLive status: counts by file status, current phase, and an ETA
session pause / resume / cancelPause a running session, resume it later, or cancel it cleanly
session rename / deleteRename a session, or delete its record and files

Batch

A batch is where the actual conversion work happens: a named group of SQL files that get discovered, planned, converted, validated, and auto-fixed together, spread across parallel workers. A session can hold more than one batch, useful for splitting a large migration into stages (a first batch for low-risk views, a second for the procedures that depend on them) without starting a new session each time.

Membership freezes when sealed

A batch starts open: keep adding files with batch add until you're ready. batch seal freezes its file list so a run always converts exactly the files you intended, nothing added later by accident.

Runs detached, watch live

batch run always starts a detached background worker and hands back immediately; batch watch attaches a live dashboard to it (or shows recent events if nothing's currently running).

Batch lifecycle commands

CommandWhat it does
batch create <session_id> -n NAMECreates a new, open batch inside a session
batch add <session_id> <batch_id> -d DIRAdds every `.sql` file in a directory to an open batch
batch seal <session_id> <batch_id>Freezes the batch's file membership so it can be run
batch run <session_id> <batch_id>Runs a sealed batch as a detached worker
batch watch <session_id> [batch_id]Live dashboard for one batch, or every batch in a session
batch pause / resume / cancelPause a running batch, resume it later, or cancel it cleanly
batch listTable of every batch in a session, with state and file counts

See Batch Conversion & Sessions for the full command reference, including reports and metrics, and Scheduled Conversions for running a sealed batch later instead of immediately.

Two Ways to Create a Batch

You rarely have to think about batches directly for a quick job: 3xcode pyspark convert --dir ./sql/ creates and runs a batch for you in one step, the same shorthand as before. Reach for the explicit batch commands when you want to build up a file list incrementally, review it before running, or schedule the run for later.

Terminal
# Shorthand: one command creates and runs an implicit batch
3xcode pyspark convert --dir ./sql/ --session "warehouse-migration" -w 4

# Explicit: build the batch up, review it, then run it
3xcode session create --name "warehouse-migration"
3xcode batch create <session_id> --name "phase-1-views"
3xcode batch add <session_id> <batch_id> --dir ./sql/views/
3xcode batch seal <session_id> <batch_id>
3xcode batch run <session_id> <batch_id>
3xcode batch watch <session_id> <batch_id>

Prefer not to type the batch commands? The local web UI (3xcode ui) has a guided batch wizard that walks through these same create, seal, and run steps, then shows live batch cards as it converts, no commands to memorize. See the Web UI.

Adaptive Workers

A batch converts files in parallel across a pool of workers, and that pool size is not fixed. Left at its default, 3xcode starts conservatively and ramps concurrency up as files keep succeeding, then backs off sharply the moment the provider signals it's overloaded, holding steady for a short cooldown before trying to grow again. A memory check and an automatic safety cutoff (which drops concurrency to a minimum if repeated failures suggest something's actually wrong, rather than just a slow moment) both sit underneath this as independent ceilings.

FlagDefaultWhat it actually controls
-w N / --workers N0 (auto)Sets the ceiling adaptive tuning is allowed to grow to, not a fixed worker count. `0` lets it grow up to a built-in default cap; a positive N caps it at N. Either way, the batch can still run with fewer workers than the ceiling if the provider pushes back or memory is tight.

In practice this means you rarely need to hand-tune -w: it exists to give you an upper bound (useful on a shared or resource-constrained machine), not a number you need to get exactly right. See Best Practices for guidance on when to set it explicitly.