Skip to content

Quick Start

PX makes parallel execution simple: pipe inputs to a command, and PX runs it across local CPU cores or cloud cluster nodes. Get up and running in under 5 minutes. This guide walks through installing PX, running your first parallel job locally, then scaling the same job out to a cloud cluster.

Prerequisites

  • uv (used to install PX)
  • A cloud account (only for the cloud steps). AWS and GCP supported during private beta; Azure and DigitalOcean coming soon.
  • The gcloud CLI for the cloud steps (this guide uses GCP).
  • Basic familiarity with the command line

Step 1: Install PX

Install PX with uv tool.

bash
uv tool install --force --no-cache --from https://px.app/releases/latest/px.tar.gz px
bash
uv tool install --force --no-cache --from https://px.app/releases/nightly/latest/px.tar.gz px

Stable is recommended. Nightly tracks the latest commits on main and may include breakage.

Why uv and these flags?

During the private beta, PX CLI releases are managed manually and we use uv tool to pull in third-party dependencies that the px tool needs.

--force --no-cache ensures you always get the latest tarball. Without these, uv may reuse a previously downloaded copy and miss a fresh upstream build.

For more on uv, see the uv documentation.

Verify the install:

bash
px --version

Step 2: Run a Parallel Job Locally

Pipe a sequence of inputs into px run. Each input becomes one task argument; PX partitions them across parallel tasks.

bash
seq 1 16 | px run -p 4 'while read line; do echo "pid=$$ arg=$line"; done'

You'll see output like:

[px] Supervisor loaded
[px]   cmd: while read line; do echo "pid=$$ arg=$line"; done
[px]   args: *via stdin
[px]   parallelism: 4
[px] ---
[px] Creating input stream...
[px] Partitioning inputs for tasks...
[px] ---
[px] Start: task=0
[px] Start: task=1
[px] Start: task=2
[px] Start: task=3
pid=2698278 arg=2
pid=2698278 arg=6
pid=2698278 arg=10
pid=2698278 arg=14
pid=2698277 arg=1
pid=2698277 arg=5
pid=2698277 arg=9
pid=2698277 arg=13
[px] Stop: task=0
[px] Stop: task=1
pid=2698280 arg=4
pid=2698280 arg=8
pid=2698280 arg=12
pid=2698280 arg=16
pid=2698279 arg=3
pid=2698279 arg=7
pid=2698279 arg=11
pid=2698279 arg=15
[px] Stop: task=2
[px] Stop: task=3

What this command did:

  • Spawned 4 tasks
  • Partitioned the 16 input lines across them (4 lines per task)
  • Each task printed its PID alongside the argument it processed

Any program, any language

The command between quotes is just a shell command. PX supports any programming language for user code, including Python, Ruby, JavaScript, TypeScript, Rust, Zig, C/C++, Go, Java, and more. For end-to-end walkthroughs, see px-systems/examples.

Step 3: Set Up Your Cloud

To run the same job on a cluster, PX needs credentials for your cloud provider. PX doesn't log you in itself. Instead, you authenticate with your cloud's own CLI and PX picks up the credentials from there.

This guide uses GCP. Authenticate with Application Default Credentials:

bash
gcloud auth application-default login

Then point gcloud at your project (list them with gcloud projects list if you're unsure):

bash
gcloud config set project <PROJECT_ID>

Now confirm PX can reach your cloud:

console
$ px doctor cloud
○ aws  disabled (credentials not configured)
       $ aws configure
       For more info: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
✓ gcp  enabled

gcp shows enabled, so you're good to go! aws might show up as disabled depending on your local environment. That's fine: PX only needs credentials for the cloud it will provision on.

On AWS instead?

The setup is the same idea with aws configure (or aws sso login). See Cloud Setup for both providers and how to read px doctor cloud.

Step 4: Generate a Cluster Spec

Generate a starter px.yaml for your cluster:

bash
px cluster generate-config

This drops a fully-commented px.yaml.example in the current directory. Copy it to px.yaml. For this example, the defaults are fine; the minimal shape looks like:

yaml
num_nodes: 3

resources:
  infra: gcp
  cpus: 2
  disk_size: 50
  ports:
    - 8020

px.yaml is a SkyPilot subset

px.yaml is a curated subset of the SkyPilot task YAML spec. The generated px.yaml.example documents every supported field; don't memorize the schema, just edit the template. For the full reference, see px.yaml.

Step 5: Bring Up the Cluster

bash
px cluster up my-cluster
Provisioning cluster 'my-cluster' (px.yaml)...
Considered resources (3 nodes):
------------------------------------------------------------------------------------
INFRA                 INSTANCE        vCPUs   Mem(GB)   GPUS   COST ($)   CHOSEN
------------------------------------------------------------------------------------
GCP (us-central1-a)   n4-standard-2   2       8         -      0.27          ✔
------------------------------------------------------------------------------------
Launching on GCP us-central1 (us-central1-a)
✓ Instances launched
✓ Workdir synced        ~/sky_logs/sky-2026-05-07-14-43-29-212699/workdir_sync.log
✓ Storage mounted       ~/sky_logs/sky-2026-05-07-14-43-29-212699/storage_mounts.log
✓ Setup completed
✓ PX runtime ready

Cloud econometric model

PX uses a real-time pricing database to pick the cheapest instance that meets your resources constraints. The "Considered resources" table shows what was evaluated and which option was chosen.

Inspect what you just provisioned:

bash
px cluster status my-cluster
ID            = e7d03c40-f129-40f1-9692-8cec9c6d6135
Name          = my-cluster
Name On Cloud = my-cluster-267fc313
Status        = up
Infra         = gcp
Region        = us-central1
Spec File     = /home/user/.sky/generated/my-cluster.yml
Created       = May 07, 12:47 UTC
Duration      = 12m

Resources
Instance   = n4-standard-2
CPUs       = 2.0 (per node)
Disk       = 50GB
Ports      = 8020
Node Count = 3

Head Node
Hostname   = my-cluster
Public IP  = 35.222.23.86
Private IP = 10.128.0.37

Worker Nodes
Hostname            Public IP      Private IP
my-cluster-worker1  34.56.115.68   10.128.0.35
my-cluster-worker2  34.63.192.212  10.128.0.36

Cost
Hourly = $0.11
Total  = $0.02

Step 6: Submit the Same Job to the Cluster

Same pipeline, now running across cloud nodes:

bash
seq 1 16 | px job submit -c my-cluster -p 4 'while read line; do echo "pid=$$ arg=$line"; done'
[px] Running command in cluster mode
[px]   cluster: my-cluster
[px]   parallelism: 4
[px]   job_id: e9665b5032c5
[px] ---
[px] Logs will stream here. Pressing Ctrl-C will stop streaming,
[px] but will not stop the job running remotely.

[stdout] [px] Supervisor loaded
[stdout] [px]   cmd: while read line; do echo "pid=$$ arg=$line"; done
[stdout] [px]   args: *via stdin
[stdout] [px]   parallelism: 2
[stdout] [px] ---
[stdout] [px] Creating input stream...
[stdout] [px] Partitioning inputs for tasks...
[stdout] [px] ---
[stdout] [px] Start: task=0
[stdout] [px] Start: task=1
[stdout] pid=7611 arg=1
[stdout] pid=7611 arg=3
[stdout] pid=7611 arg=5
[stdout] pid=7611 arg=7
[stdout] pid=7611 arg=9
[stdout] pid=7613 arg=2
[stdout] pid=7613 arg=4
[stdout] pid=7613 arg=6
[stdout] pid=7613 arg=8
[stdout] pid=7613 arg=10
[stdout] [px] Stop: task=0
[stdout] [px] Stop: task=1
[stdout] [px] Supervisor loaded
[stdout] [px]   cmd: while read line; do echo "pid=$$ arg=$line"; done
[stdout] [px]   args: *via stdin
[stdout] [px]   parallelism: 2
[stdout] [px] ---
[stdout] [px] Creating input stream...
[stdout] [px] Partitioning inputs for tasks...
[stdout] [px] ---
[stdout] [px] Start: task=0
[stdout] [px] Start: task=1
[stdout] pid=7688 arg=11
[stdout] pid=7688 arg=13
[stdout] pid=7688 arg=15
[stdout] pid=7690 arg=12
[stdout] pid=7690 arg=14
[stdout] pid=7690 arg=16
[stdout] [px] Stop: task=0
[stdout] [px] Stop: task=1

[px] Job completed

Why does each worker show parallelism: 2?

You asked for -p 4 total parallelism. PX divides that across the 2 workers in your cluster, giving 2 parallel tasks per worker. The full banner prints once per worker because each worker runs its own local supervisor.

[stdout] and [stderr] prefixes appear because px job submit streams both channels by default; pass --stream stdout or --stream stderr to filter.

Step 7: Inspect Jobs

List jobs on the cluster:

bash
px job ls -c my-cluster
JOB_ID        COMMAND                                            STATUS     PROGRESS  PARALLELISM  CREATED
e9665b5032c5  while read line; do echo "pid=$$ arg=$line"; done  completed  100.0%    4            3m ago

Drill into one:

bash
px job status -c my-cluster e9665b5032c5
ID          = e9665b5032c5
Command     = while read line; do echo "pid=$$ arg=$line"; done
Parallelism = 4
Status      = completed
Created     = May 07, 12:51 UTC
Started     = May 07, 12:51 UTC
Completed   = May 07, 12:51 UTC

Progress
Total Args = 16
Processed  = 16
Failed     = 0
Progress   = 100.0%

To re-stream the logs of a completed (or live) job, use px job logs -c my-cluster <job_id>.

Step 8: Tear Down

When you're done, terminate the cluster to stop billing:

bash
px cluster down my-cluster
Terminating cluster my-cluster...
✓ Cluster terminated

Next Steps