dstack 0.21.0 is a major release that migrates the codebase to Pydantic v2, introduces new features, and removes a number of previously deprecated features. New 0.21.x CLIs do not work with older 0.20.x servers. New servers continue to support older CLIs, so ensure to update the server and the CLI at the same time or update the server first.
Pydantic v2
dstack has finally migrated from Pydantic v1 to Pydantic v2. Besides faster validation and serialization and faster CLI startup, the migration unblocks Python 3.14 support and integration with latest Python libraries.
If you use the Python API or have dstack plugins installed, ensure the code works with Pydantic v2 models before upgrading dstack.
Python 3.14
dstack now supports Python 3.14 both for installing dstack and inside runs:
type: dev-environment
ide: vscode
python: "3.14"Gateways
Replicated gateways with HTTPS
Replicated gateways previously required an external load balancer for TLS termination. AWS gateways with an acm certificate can now have more than one replica with HTTPS handled by dstack:
type: gateway
name: example-gateway
backend: aws
region: eu-west-1
domain: example.com
certificate:
type: acm
arn: arn:aws:acm:eu-west-1:164099421079:certificate/3670388f-f43b-4872-aaf8-907b107a170d
replicas: 2Load balancing across replicas is performed by a single ALB associated with the gateway, which becomes the gateway's hostname:
$ dstack gateway list
NAME BACKEND HOSTNAME DOMAIN DEFAULT STATUS
example-gateway dstack-qe1na76o-lb-187858581.eu-west-1.elb.amazonaws.com example.com ✓ running
replica=0 aws (eu-west-1) 18.202.25.65 running
replica=1 aws (eu-west-1) 3.255.100.238 runningReplicated gateways remain experimental. For other backends and certificate types, an external load balancer is still required for TLS termination.
CLI
Improved dstack metrics
dstack metrics now shows CPU, memory, and GPU utilization over the last hour of the job, allowing to track changes in metrics:
$ dstack metrics gentle-mayfly-1
UTILIZATION MEMORY
cpu ▅▄▄▄▃▃▃▃▃▃▃▃▃▃▃▃▅▅▄▃▃▃▃▃▃▃▃ 41% of 128 ▃▃▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ 581GB/960GB
gpu=0 ▁▂▃▆▆▆▆▆▆▆▆▆▆▆▆▆▆▁▆▆▆▆▆▆▆▆▆ 89% ▄▅▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆ 71GB/80GB
gpu=1 ▁▂▆▆▆▅▆▆▆▆▆▆▆▆▆▆▁▁▅▆▆▅▆▆▆▆▆ 84% ▄▅▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆ 71GB/80GB
gpu=2 ▁▂▆▆▆▆▆▆▆▆▆▆▆▆▆▆▁▆▆▆▆▆▆▆▆▆▆ 87% ▄▅▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆ 71GB/80GB
gpu=3 ▂▃▆▅▅▅▅▅▅▆▅▅▆▆▆▆▁▅▅▅▅▅▆▅▅▅▅ 82% ▄▅▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆ 71GB/80GB
4 Aug 14:10 ┄┄┄┄┄┄┄┄┄┄┄ now 4 Aug 14:10 ┄┄┄┄┄┄┄┄┄┄┄ nowLike dstack logs, the command now shows a single job: --replica and --job select one, both defaulting to 0.
GPU driver
dstack fleet -v now shows a DRIVER column with the accelerator driver installed on the host (NVIDIA, AMD, or Tenstorrent), also available as Instance.gpu_driver in the API. The driver is detected by dstack-shim and refreshed on instance checks, so it is filled in for existing instances after an upgrade and updated after a driver upgrade on the host. Container-based backends report no driver for now.
Offers
dstack offer and dstack apply gain two new flags: --full-offers and --unallocated (and corresponding full_offers and unallocated_resources API parameters):
--full-offersrequests not to adjust offers by requirements on backends that pack multiple jobs onto a node and return full node resources. Currently supported by Kubernetes and Slurm backends.--unallocatedsubtracts already-allocated resources on backends that pack multiple jobs onto a node, so offers reflect only the available capacity. Currently supported by Kubernetes backend.
The flags are discovery-only.
Presets
dstack preset create gains a pinned benchmark workload, a baseline trial to measure against, and a per-trial record of what each trial taught. The properties that decide what "verified" means are now required rather than optional, so two creations from the same configuration produce comparable presets.
type: preset
name: dsv4-flash
# The agent picks a compatible variant of the base model
base: deepseek-ai/DeepSeek-V4-Flash
# Consider only the specified fleets
fleets: [b200-2x]
# The requirements the preset must meet (time to first token is in milliseconds)
min_context_length: 1048576
max_ttft: 675
# The number of simultaneous requests every benchmark uses
concurrency: 1
# The request shape every benchmark uses (defaults to 1024 and 1024)
input_tokens: 10000
output_tokens: 1500
# Make the first trial a reference point rather than an optimization attempt
baseline: true
# The number of benchmarked trials
trials: 10Each trial now records what it learned, whether it broke a constraint, and the largest context it actually handled, so context_length on a saved preset is measured rather than assumed. A trial that breaks a constraint keeps its benchmark for the next trial to learn from and is excluded from best-trial selection.
dstack preset gains ps-style filtering with -a, -n, --base, and --repo, CONSTRAINTS and BENCHMARK columns, and one glyph per trial:
$ dstack preset -a --base deepseek-ai/DeepSeek-V4-Flash
ID BASE GPU CONSTRAINTS BENCHMARK STATUS SUBMITTED
c83375b4 deepseek-ai/DeepSeek-V4-Flash B200:180GB:2 io=10000/1500 conc=1 tok/s/user=319 ttft=220ms ctx=1M interrupted (5/10) 8 hours ago
de7a07c1 deepseek-ai/DeepSeek-V4-Flash B200:2 io=10000/1500 conc=1 tok/s/user=140 ttft=519ms ctx=1M verified (5) 19 hours ago
014c3216 deepseek-ai/DeepSeek-V4-Flash H100:80GB:4 io=8K/1K prefix=90% conc=648 tok/s/user=11.2 ttft=4.89s ctx=1M verified (8) yesterdayPresets remain an experimental feature. The configuration properties changed in a backward-incompatible way, see the breaking changes below.
Backends
AWS
The AWS backend gains an experimental_instance_types setting that allows provisioning instance types outside the standard supported families, as long as they are present in dstack's pricing catalog:
projects:
- name: main
backends:
- type: aws
creds:
type: default
experimental_instance_types: [p5en.48xlarge]$ dstack offer -b aws --instance-type p5en.48xlarge
# BACKEND RESOURCES INSTANCE TYPE PRICE
1 aws (us-east-2) cpu=192 mem=2048GB disk=100GB gpu=H200:141GB:8 (spot) p5en.48xlarge $26.6319
2 aws (us-west-2) cpu=192 mem=2048GB disk=100GB gpu=H200:141GB:8 (spot) p5en.48xlarge $26.9512
3 aws (us-east-2) cpu=192 mem=2048GB disk=100GB gpu=H200:141GB:8 p5en.48xlarge $63.296Slurm
Slurm offers no longer report a fake disk size derived from the requested disk.size range. Disk size is now reported as unknown, and offers are no longer filtered by the disk requirement instead of promising storage that may not be there.
Breaking changes
- The
dstackPython API and plugins now work with Pydantic v2 models. Update the code before upgradingdstack. - Dropped the
/api/project/{project_name}/runs/submitendpoint, deprecated in favor of/api/project/{project_name}/runs/apply. - Dropped the
/api/project/{project_name}/fleets/createendpoint, deprecated in favor of/api/project/{project_name}/fleets/apply. - Dropped the top-level
routerproperty from gateway and run configurations, deprecated since 0.20.17 in favor of replica-based routers. - The server no longer accepts
resources.cpuas an integer range in the request format used by clients older than 0.19.8. Upgrade the CLI and API clients before upgrading the server. - UTC datetimes are serialized as
Zinstead of+00:00. - Preset configurations (experimental):
max_trialsis nowtrials,context_lengthis nowmin_context_length, andmax_ttft,min_context_length, andconcurrencyno longer have defaults. Existing configurations fail withextra fields not permitted; no aliases were added.
Deprecations
Resources.description,Gateway.backend, andGateway.regionare no longer populated by the server and are excluded by the client. They will be removed in 0.22.
What's Changed
- Use test log storage in
test_updates_running_jobby @un-def in #4065 - Add
full_offersoption toCompute.get_offers()by @un-def in #4060 - Add in-place update for gateway
replicasby @jvstme in #4014 - Set dstack.user.name attr on OTel traces by @r4victor in #4068
- Add support for offers with unknown disk size by @un-def in #4066
- Add
unallocated_resourcesoption toCompute.get_offers()by @un-def in #4067 - Add AWS
experimental_instance_typessetting by @jvstme in #4069 - Prepare for Pydantic v2 migration by @r4victor in #4072
- Support replicated AWS gateways with ACM by @jvstme in #4071
- Add pydantic compatibility tests by @r4victor in #4073
- Show host GPU driver on fleet instances by @peterschmidt85 in #4032
- Fix TCP port range validation by @ShiroKSH in #4075
- Migrate to Pydantic v2 by @r4victor in #4077
- Fix BackendsAPIClient.config_info by @r4victor in #4080
- [chore]: Drop redundant Pydantic variable annotations by @jvstme in #4082
- Add dstack user agent to Nebius SDK by @complynx in #4084
- Force rich non-terminal output in tests by @r4victor in #4081
- [Internal] Add just recipes for running Python tests via tox by @un-def in #4083
- Speed Python up tests with session-scoped db fixtures by @r4victor in #4088
- Stop preset tests from waiting on the tail poll by @r4victor in #4089
- Regenerate pydantic_compat fixtures by @un-def in #4090
- [CLI] Fix --cpu and --gpu argument parsers by @un-def in #4092
- Prepare gateway API for state sync mechanism by @jvstme in #4087
- Fix extra run/fleet configuration properties not ignored when parsing by @r4victor in #4098
- [Breaking]: Drop gateway-based routers by @jvstme in #4097
- Drop support for ResourcesSpec.cpu as Range[int] by @un-def in #4091
- Improve
dstack fleettable readability and ordering by @peterschmidt85 in #4093 - Visualize
dstack metricsas sparklines by @peterschmidt85 in #4086 - Update future release references 0.20.30 -> 0.21.0 by @jvstme in #4100
- Improve preset creation harness by @peterschmidt85 in #4078
- Add
for_offers_onlyparameter to/runs/get_planAPI method by @un-def in #4104 - Dim the interrupted preset status by @peterschmidt85 in #4105
- Drop pre-0.21 compatibility code by @r4victor in #4103
- Add 0.21 section to the upgrade guide by @r4victor in #4106
New Contributors
Full Changelog: 0.20.29...0.21.0