0.20.0
dstack 0.20 is a major release that brings significant improvements and introduces a number of breaking changes. Read below for the most important ones. For migration notes, please refer to the migration guide.
Fleets
dstack previously had two different ways to provision instances for runs: using a fleet configuration or using automatic fleet provisioning on run apply. To unify the UX, dstack no longer creates fleets automatically.
Fleets must now be created explicitly before submitting runs. This gives users full control over the provisioning lifecycle. If you don't need any limits on instance provisioning (as was the case with auto-created fleets), you can create a single elastic fleet for all runs:
type: fleet
name: default-fleet
nodes: 0..Note that multi-node tasks require fleets with placement: cluster, which provides the best possible connectivity. You will need a separate fleet for each cluster.
Note
To keep the old behavior with auto-created fleets, set the DSTACK_FF_AUTOCREATED_FLEETS_ENABLED environment variable.
Runs
Working directory
Previously, the working_dir property had complicated semantics: it defaulted to /workflow, but for tasks and services without commands, the image's working directory was used instead.
This has now been simplified: working_dir always defaults to the image's working directory. The working directory of the default dstack images is now set to /dstack/run.
Repo directory
Working with repos is now more explicit and intuitive. First, dstack now only sets up repos that are explicitly defined in run configurations via repos; repos initialized with dstack init are not set up unless specified:
type: dev-environment
ide: vscode
repos:
# Clone the repo in the configuration's dir into `working_dir`
- .Second, repos[].path now defaults to working_dir (".") instead of /workflow.
Third, cloning a repo into a non-empty directory now raises an error so that mistakes are not silently ignored. The previous behavior of skipping cloning can be specified explicitly with if_exists: skip:
type: dev-environment
ide: vscode
repos:
- local_path: .
path: /my_volume/repo
if_exists: skipEvents
dstack now stores important events—such as resource CRUD operations, status changes, and other information crucial for auditing and debugging. Users can view events using the dstack event CLI command or in the UI.
$ dstack event
[2025-12-11 15:05:20] [👤admin] [run clever-cheetah-1] Run submitted. Status: SUBMITTED
[2025-12-11 15:05:20] [job clever-cheetah-1-0-0] Job created on run submission. Status: SUBMITTED
[2025-12-11 15:05:26] [job clever-cheetah-1-0-0, instance cloud-fleet-0] Job assigned to instance. Instance status: BUSY (1/1 blocks busy)CLI
JSON output
The dstack ps and dstack gateway commands now support --format json / --json arguments that print results in JSON instead of plaintext:
$ dstack ps --json
{
"project": "main",
"runs": [
{
"id": "5f2e08b5-2098-4064-86c7-0efe0eb84970",
"project_name": "main",
"user": "admin",
"fleet": {
"id": "9598d5db-67d8-4a2e-bdd2-842ab93b2f2e",
"name": "cloud-fleet"
},
...
}
]
}Verda (formerly Datacrunch)
The datacrunch backend has been renamed to verda, following the company's rebranding.
projects:
- name: main
backends:
- type: verda
creds:
type: api_key
client_id: xfaHBqYEsArqhKWX-e52x3HH7w8T
client_secret: B5ZU5Qx9Nt8oGMlmMhNI3iglK8bjMhagTbylZy4WzncZe39995f7Vxh8
Gateways
Gateway configurations now support an optional instance_type property that allows overriding the default gateway instance type:
type: gateway
name: example-gateway
backend: aws
region: eu-west-1
instance_type: t3.large
domain: example.comCurrently instance_type is supported for aws and gcp backends.
All breaking changes
- Fleets are no longer created automatically on run apply and have to be created explicitly before submitting runs.
- The run's
working_dirnow always defaults to the image's working directory instead of/workflow. The working directory ofdstackdefault images is now/dstack/run. repos[].pathnow defaults toworking_dir(".") instead of/workflow.- Dropped implicitly loaded repos; repos must be specified via
reposconfiguration property. - Cloning a repo into a non-empty directory now raises an error. This can be changed by setting
if_exists: skip. - Dropped CLI commands
dstack config,dstack stats, anddstack gateway create. - Dropped Python API
RunCollectionmethodsRunCollection.get_plan(),RunCollection.exec_plan(), andRunCollection.submit(). - Dropped local repos support:
dstack init --localanddstack.api.LocalRepo. - Dropped Azure deprecated VM series Dsv3 and Esv4.
- Dropped legacy server environment variables
DSTACK_SERVER_METRICS_TTL_SECONDSandDSTACK_FORCE_BRIDGE_NETWORK.
Deprecations
- Deprecated the API endpoint
/api/project/{project_name}/fleets/createin favor of/api/project/{project_name}/fleets/apply. - Deprecated
repo_dirargument inRunCollection.get_run_plan()in favor ofrepos[].path.
What's Changed
- Update alembic pin by @r4victor in #3331
- [Internal] Bump golangci-lint to v2 by @un-def in #3336
- Add RELEASE.md by @r4victor in #3334
- Implement runner auto-update by @un-def in #3333
- [Feature]: Add JSON output option for CLI commands by @peterschmidt85 in #3335
- [Docs] Make Kapa.ai a sidebar (styling update) by @peterschmidt85 in #3338
- [Docs] Fleet-related improvements by @peterschmidt85 in #3339
- [UI] Run Wizard. Added docker, python and repos fields by @olgenn in #3252
- Make autocreated fleets opt-in by @r4victor in #3342
- Add
repos[].if_existsrun configuration option by @un-def in #3341 - Clean up 0.19 compatibility code by @r4victor in #3347
- [Breaking]: Drop deprecated
RunCollectionmethods by @jvstme in #3340 - Events emission framework and API by @jvstme in #3325
- Drop legacy server environment variables by @un-def in #3349
- Drop legacy working/repo dirs where possible by @un-def in #3348
- refactor: just remove 3 duplicated lines in 1 .py file by @immanuwell in #3350
- Drop
dstack config,dstack stats,dstack gateway createby @r4victor in #3351 - Drop hardcoded Hot Aisle VM specs by @jvstme in #3239
- [Docs]: Fix TensorDock still present in reference by @jvstme in #3321
- [Blog] How Toffee streamlines inference and cut GPU costs with
dstackby @peterschmidt85 in #3345 - Drop config.yml->repos and LocalRepo support by @un-def in #3352
- [chore]: Fix Alembic
path_separatorwarning by @jvstme in #3353 - Clean up low- and high-level API clients by @un-def in #3355
- Add
EventTarget.project_nameby @jvstme in #3362 - [runner] Chown repo dir by @un-def in #3364
- Add tini to server Docker images by @un-def in #3357
- Set WORKDIR in base Docker images by @un-def in #3358
- #3309 events UI by @olgenn in #3361
- Pass state param to github callback by @r4victor in #3366
- Add the
dstack eventcommand for viewing events by @jvstme in #3365 - [Internal] Packer: apt-upgrade.sh: autoaccept conffiles changes by @un-def in #3367
- Bump base_image to 0.12 by @un-def in #3368
- Restore
RunSpec.working_dirfield by @un-def in #3371 - Drop
DSTACK_FF_EVENTSby @jvstme in #3372 - Change field order in
dstack eventby @jvstme in #3373 - Add more events by @jvstme in #3369
- [Verda] Rename the
datacrunchbackend toverdaby @peterschmidt85 in #3359 - [Docs] Added Migration guide (for the upcoming 0.20) by @peterschmidt85 in #3374
- Set pyright typeCheckingMode by @r4victor in #3379
- Run frontend-pre-commit only on frontend files by @r4victor in #3380
- [Docs] Add
Crusoeexample underClustersby @peterschmidt85 in #3381 - Allow customizing gateway instance type by @jvstme in #3384
- [Docs] Merge GCP clusters examples by @peterschmidt85 in #3376
- [Docs] Updated the AWS example under
Clustersby @peterschmidt85 in #3387 - [Docs] Merged NCCL and RCCL tests examples under
Clustersinto one by @peterschmidt85 in #3388 - Use TTLCache for _BACKENDS_CACHE by @r4victor in #3389
- [Docs]: Add
dstack eventCLI reference page by @jvstme in #3375 - Handle BackendAuthError when getting project backends by @r4victor in #3393
- [UX] Increase secret length from
3000to5000by @peterschmidt85 in #3391 - Relax event message validation rules by @jvstme in #3394
New Contributors
- @immanuwell made their first contribution in #3350
Full Changelog: 0.19.40...0.20.0