Best Practices

Practical, batch-first guidance for getting reliable, cost-effective results out of the 3XCode CLI, grounded in how the conversion pipeline and quota system actually behave.

Organize with Workspaces

A workspace is the unit of organization for a migration: it owns its own input/, output/, .sessions/, and logs/ directories. Create one workspace per logical migration (a schema, a domain, a client engagement) rather than dumping unrelated SQL into a single catch-all workspace.

Set up a dedicated workspace
3xcode workspace init ./billing-migration --name "billing-migration"
3xcode workspace status
3xcode workspace list
3xcode workspace prune

Right-Size Your Batches

A session can hold more than one batch. For a large migration, split it into batches by domain or dependency stage (views first, then the procedures that depend on them) rather than one giant batch covering everything. Smaller batches finish sooner, produce a report sooner, and let you fix real problems in an early batch before they repeat across a much larger one.

--sort controls ordering within a batch

simple-first (default) surfaces quick wins early; complex-first front-loads the highest-complexity objects if you'd rather find problems immediately.

Name every batch and session

Descriptive --name values make batch list and session list meaningful later, especially once you're running several batches per migration.

Split a migration into staged batches
3xcode session create --name "billing-migration"

3xcode batch create <session_id> --name "phase-1-views" --dir ./sql/views/
3xcode batch seal <session_id> <batch_id_1>
3xcode batch run <session_id> <batch_id_1>

# Once phase 1 finishes cleanly, start the next stage
3xcode batch create <session_id> --name "phase-2-procedures" --dir ./sql/procedures/
3xcode batch seal <session_id> <batch_id_2>
3xcode batch run <session_id> <batch_id_2>

Let Workers Auto-Tune

-w / --workers sets a ceiling, not a fixed worker count. Left at its default (0), a batch starts conservatively and ramps concurrency up as files keep succeeding, backing off automatically the moment the AI provider pushes back or memory gets tight. Hand-picking a specific worker count usually just recreates what auto-tuning already does, more slowly.

Set a ceiling when it matters

On a shared or resource-constrained machine, pass -w N to cap how high concurrency is allowed to climb. It's a safety limit, not a target to hit.

Detached runs are capped too

Every batch run (always detached) shares a hard, machine-wide cap of 3 concurrent detached workers, regardless of workspace.

Terminal
# Default: let it auto-tune
3xcode batch run <session_id> <batch_id>

# Cap it explicitly on a shared machine
3xcode batch run <session_id> <batch_id> --workers 4

Start with --dry-run

Before committing to a full run on a large or unfamiliar batch of SQL, run --dry-run first. It executes only discovery and planning: dialect detection, platform fingerprinting, the full object inventory, complexity scoring, and the dependency-ordered conversion plan, with no PySpark code generated. pyspark analyze does the same for a single file.

Preview before converting
3xcode pyspark convert --dir ./sql/ --dry-run
3xcode pyspark analyze legacy_proc.sql

Discovery and planning still require login and a valid license, this isn't a free or offline operation, since it makes real AI calls. The savings come from skipping conversion, validation, and auto-fix, not from skipping the model entirely.

Schedule Big Runs Off-Hours

A large batch competes with everything else you do on the same machine, and with your own attention if you're watching it live. For anything sizeable, seal the batch and schedule it to run overnight or over a weekend instead of kicking it off in the middle of your working day.

Terminal
# Seal it, then wake it up tonight
3xcode batch seal <session_id> <batch_id>
3xcode batch schedule <session_id> <batch_id> --at 2026-07-16T22:00

# Or a durable, repeating off-hours schedule that survives a reboot
3xcode schedule add <session_id> <batch_id> --at 2026-07-17T02:00 --repeat daily

Two mechanisms, different guarantees

batch schedule is a lightweight one-off wake-up; the schedule command group is durable and survives a reboot. Pick durable scheduling for anything you can't afford to silently miss because the machine restarted. See Scheduled Conversions.

Triage by Confidence Band

Don't review a finished batch in file order. Read BATCH_SUMMARY.md first, then work through the Low band, then Medium, then spot-check High and Perfect. This puts your attention where the pipeline itself flagged the most risk, instead of spreading it evenly across files that don't need equal scrutiny.

Review order

BandRangeAction
LowBelow 70Review first, full read of the audit
Medium70-89.99Review next, focus on manual-review items
High90-99.99Spot check
Perfect100Quick glance

Billing doesn't depend on the band, a Low-confidence file that completed the pipeline is billed the same as a Perfect one, so triaging by band is purely about where to spend your review time. See Billing & Quota.

Org Quota Hygiene

If your team has a shared org quota, a few habits keep everyone from surprising each other. Check 3xcode org me before kicking off a large batch to see whether you're drawing from a shared pool or a per-seat allotment, and prefer scheduling a very large batch rather than running it at the exact moment a teammate might need quota too.

Check before a big run

3xcode org me shows shared-license status and mode; 3xcode status shows your own individual usage regardless of org membership.

Cancel promptly if you don't need the rest

Cancelling a batch you no longer need releases its unused quota hold immediately, back to the shared pool if that's where it came from.

Use BYOK for Cost Control on Large Migrations

Every plan tier has a monthly conversion cap: Free: 5, Pro: 200, Team: 1,000, Enterprise: unlimited. For a migration that will blow past a per-tier monthly limit, or where you'd rather bill conversion cost directly to your own provider account, Bring Your Own Key (BYOK) routes conversion calls straight to Anthropic, AWS Bedrock, Google Vertex AI, or Azure AI Foundry using your own credentials instead of the platform-provided key.

Set up BYOK
3xcode contact-admin -m "Please enable BYOK for my account"
3xcode keys store --provider anthropic
3xcode keys test --provider anthropic
3xcode keys status

Verify Spark SQL Passthrough Decisions

When discovery classifies a file's dialect as spark_sql (genuine Databricks SQL or Hive), it's already running on the same engine as the PySpark target. The conversion decision is about idiom and readability, not semantics, and the pipeline may reasonably choose to keep a block as a spark.sql("...") passthrough rather than rewriting it into the DataFrame API.

Don't accept either direction blindly

Review which one the agent chose for each spark_sql object and confirm it matches your team's actual style and maintainability preferences, rather than assuming a DataFrame rewrite is automatically the better outcome.

Quick Reference Checklist

Before You Start

Dedicated workspace initialized. BYOK configured if this migration will exceed your tier's monthly conversion cap.

Before You Run

Ran --dry-run or pyspark analyze. Batch right-sized and named. Scheduled off-hours if it's large.

While It Runs

Left -w at its default unless a specific ceiling is needed. Checked org quota status if quota is shared.

Before You Ship

Read BATCH_SUMMARY.md, triaged Low and Medium bands first, resolved requires_manual items, and reviewed spark_sql passthrough choices.

PracticeCommand
Scope a migration to its own workspace3xcode workspace init ./path --name "migration-name"
Preview before spending on a full run3xcode pyspark convert --dir ./sql/ --dry-run
Right-size and name a batch3xcode batch create <session_id> --name "phase-1" --dir ./sql/
Schedule a large batch off-hours3xcode batch schedule <session_id> <batch_id> --at 2026-07-16T22:00
Check shared quota before a big run3xcode org me
Triage the finished batch by bandRead `BATCH_SUMMARY.md`, starting with the Low band
Route large migrations to your own provider key3xcode keys store --provider anthropic