Skip to main content
Are you a large language model? This page is available as raw markdown at /configuration.md. The full docset is at /llms-full.md and the index is at /llms.md.

Project configuration

A .c3 YAML file at the root of your project describes the job. Run c3 deploy from that folder or any folder below it. c3 init writes a starter file.

project: my-experiment
script: run.sh
hardware: l40
time: "04:00:00"

python:
project: ./

datasets:
- ref: /datasets/imagenet
mount: /data/imagenet

output:
- ./checkpoints
- ./results

Fields​

FieldRequiredDescription
scriptyesBash script to run, relative to .c3
projectnoName, lowercase letters, digits and hyphens. Generated by c3 init
hardwarenoA class (l40, a100, h100) or an exact profile. Omit to let C3 choose. See Hardware
timenoMaximum runtime as "HH:MM:SS". Default one hour. You pay only for time used
job_namenoDisplay name in c3 squeue and the dashboard
python.projectnoDirectory with pyproject.toml and uv.lock. See Environments
docker.imagenoPublic Docker Hub or ghcr.io image. Cannot be combined with python
docker.requires_acceleratornocuda or none. C3 refuses a mismatched machine before the script runs
datasetsnoList of ref and optional mount. See Datasets
outputnoDirectories to collect as results. See Artifacts
providernoPin a provider such as nebius. Omit to auto-route
regionsnoAllowlist of provider region IDs. Omit for any region
capacity.on_unavailablenowait (default) or fail when the provider has no stock. See Hardware
capacity.max_wait_minutesnoHow long to wait for stock, 1 to 360. Default 60
ignore_filenoIgnore rules file to use instead of .c3ignore
api_keynoLocal credential. Stripped from the uploaded copy. See Authentication
gpunoOlder alias for hardware. Do not set both

Comments are allowed: # at the start of a line or after a value. Quote values that contain #.

What gets uploaded​

c3 deploy uploads the regular files under the folder containing .c3. It always skips .git/, node_modules/, Python virtual environments and caches, compiled Python files, shared libraries, symlinks and OS metadata. Everything else is included, including .env files, lock files and any data you have left in the folder.

Every file is hashed on every deploy and only new content is transferred, so code is cheap to redeploy. Large inputs are not: keep them out of the project folder and upload them once as a dataset instead.

Preview the selection without uploading or signing in:

c3 deploy --list-files
c3 deploy --list-files --json # {"files":[".c3","run.sh","src/train.py"]}

Exclude files​

Add a .c3ignore next to .c3. It uses .gitignore syntax:

.env
.env.*
!.env.example
results/
scratch/

To reuse your .gitignore instead:

ignore_file: .gitignore

To combine both, keep .c3ignore and import:

#!include:.gitignore
scratch/

Rules: *.log matches at any depth, /local.txt only at the root, results/ matches directories, !pattern re-includes, last match wins. Built-in exclusions cannot be undone. Excluding the script is an error. Ignore rules affect only the workspace upload, not datasets or results.

Machine-readable output​

c3 deploy --json prints one JSON object to stdout after submission and nothing else. It cannot be combined with -f.

FieldMeaning
idJob ID
statusInitial state, normally PENDING
provider, regionSelected route, null until assigned
hardware_profileExact profile selected, when known
hardware_kind, accelerator_kindgpu or cpu; cuda or none
dashboard_urlJob page in the dashboard
pull_commandThe c3 pull command for this job

c3 squeue --json returns the same jobs as the table, as an array with lifecycle timestamps, route and the latest attempt's machine ID.

Migrating a Slurm script​

c3 deploy job.sbatch still works and reads #SBATCH --time and --job-name. Convert it once with c3 migrate job.sbatch, which writes the equivalent .c3.

Deploy telemetry​

Each c3 deploy sends a short operational summary to C3: timings, outcome, selected route and aggregate file counts. No file names, contents or paths. See Telemetry and privacy.