Known issues
Artifact version deletion via the API is broken in this release and will be fixed in 0.96.3. Artifact versions can still be deleted using the python SDK:
from zenml.client import Client
Client().delete_artifact_version(..., server_side=False)Dynamic pipelines
- Explicit start ordering for dynamic steps: Dynamic pipelines now support
start_after=...when calling steps, letting you control which concurrently launched steps should wait for others before starting. This makes it easier to model ordering constraints without turning concurrent parts of a dynamic pipeline into fully synchronous execution. Note thatstart_afteris now a reserved step keyword, so steps that previously used a parameter with this name will need to be updated. PR #4995 - More flexible dynamic step inputs: You can now configure whether JSON-serializable raw values passed to steps in dynamic pipelines should be treated as parameters instead of artifacts. The new environment-variable threshold defaults to
0to preserve existing behavior, while explicit APIs such aswith_options(parameters=...)andExternalArtifact(...)remain available when you want to force either behavior. PR #5079 - Improved dynamic execution semantics: Dynamic pipelines now support
CONTINUE_ON_FAILUREexecution mode, allowing already queued or asynchronous work to continue when an async step fails. ZenML also models implicit dependencies from newly launched steps to the last completed sync step, making mixed sync/async dynamic pipelines execute in a more predictable order. PR #5052
Integrations and deployment
- DigitalOcean integration: ZenML now includes a first-class
digitaloceanintegration with support for DigitalOcean Spaces artifact stores and DigitalOcean Container Registry stack components. Spaces support builds on the existing S3-compatible implementation while handling DigitalOcean regions and endpoint generation for you. PR #5054 - Helm chart logging and OpenTelemetry configuration: The ZenML Helm chart now exposes server logging options and OpenTelemetry settings directly in values. You can configure console or JSON logging, service names, OTEL endpoints, and enable or disable traces, metrics, and logs without custom chart modifications. PR #5048
Data and metadata management
- Server-side artifact data deletion: ZenML can now delete artifact version data through the server API, not only from a full client with direct stack access. This enables artifact metadata and backing data to be deleted from the UI or from thin clients that do not have the artifact store stack component locally available. PR #5034
- Project metadata: Projects now support arbitrary
project_metadataon create, update, and hydrated response models. Metadata is stored as portable JSON, preserved when omitted, replaced when explicitly supplied, and can be cleared by sending an empty object. PR #5086
Performance and scalability
- Lower-memory cross-filesystem copies:
fileio.copy()now streams cross-filesystem copies in bounded chunks instead of reading the entire file into memory. This significantly reduces peak memory usage for local-to-remote and remote-to-local artifact operations, includingPathMaterializer, directory copies, integration materializers, and code archive upload/download flows. PR #5031 - Fewer server requests during runs: ZenML now caches commonly reused project, store, stack, pipeline run, and completed step run responses in process where safe. Local and in-process execution paths make substantially fewer server requests, which improves responsiveness for pipelines with many steps. PR #5036 PR #5038
- Faster DAG endpoint on large runs: The DAG endpoint now does less unnecessary parsing and object construction when serving large pipeline graphs. In benchmarks on a DAG with thousands of nodes and edges, endpoint latency was reduced by roughly half. PR #5051
Security and dependencies
- FastAPI, Starlette, and OpenTelemetry updates: ZenML now supports FastAPI
0.138.0, raises the lower Starlette bound to0.46.0to pick up security fixes, and updates OpenTelemetry packages for compatibility. The update also removes an unusedfastapi_utilsdependency and cleans up deprecated FastAPI response and lifespan usage. PR #5017 PR #5060
Fixed
- Token invalidation after credential changes: User tokens issued before a password change are now rejected, and tokens derived from API keys are tied to the key generation so rotated keys no longer leave stale sessions usable. The dashboard also correctly rotates API keys when a non-zero retention period is configured. PR #5025 PR #1088
- Docker credentials supplied at runtime: ZenML now properly handles in-memory Docker credentials when a local Docker credential store already has entries for the same registry. This prevents the Docker Python client from silently preferring stale local credentials over credentials passed through ZenML. PR #5023
- Remote image builds with restrictive
.dockerignorefiles: ZenML no longer includes the root.dockerignorein generated build context archives for remote builders. This fixes builds on AWS CodeBuild, GCP Cloud Build, Kaniko, and similar builders when allowlist-style ignore patterns would otherwise exclude ZenML-generated files. PR #5033 - Cleaner replay configurations: When replaying a pipeline run, ZenML now removes step parameters from the configuration if they are overridden by an input artifact. The displayed configuration no longer contains outdated values that were not actually used as step inputs. PR #5040
- Deployment invocation with dict parameters: Dict-valued pipeline parameters sent to a deployment
/invokeendpoint now replace compiled defaults instead of being recursively merged with them. This matches normal pipeline invocation behavior and prevents default keys from leaking into step inputs. PR #5042 - Dynamic pipeline DAG race condition: ZenML now avoids a race where a step run could be visible in the database before its configuration was committed. This prevents intermittent 500 errors from the DAG endpoint while dynamic pipeline steps are being created. PR #5053
- SSH orchestrator re-runs: SSH orchestrator container and Compose service names now avoid collisions across multiple runs of the same snapshot. Re-running from the dashboard, templates, or concurrent triggers no longer fails because an old container with the same name still exists on the host. PR #5082
What's Changed
- Add version 0.96.0 to legacy docs by @github-actions[bot] in #5021
- Remove placeholder data on queue full errors by @Json-Andriopoulos in #5027
- Support secret references in secret strings by @schustmi in #5024
- Bump FastAPI version by @schustmi in #5017
- Expire tokens after password changes and API key rotations by @stefannica in #5025
- Fix the in-memory docker credentials properly by @stefannica in #5023
- Remove deprecated workspace-local service accounts in ZenML Pro by @stefannica in #5032
- Stream cross-filesystem file copies in chunks by @kounelisagis in #5031
- Misc query improvements by @schustmi in #5035
- Don't include dockerignore in build context archive by @schustmi in #5033
- Reduce unnecessary server requests by @schustmi in #5036
- Remove shadowed step parameters when replaying by @schustmi in #5040
- Allow workspace service accounts for a little while longer by @stefannica in #5041
- Fix dict parameter overrides when invoking deployments by @kounelisagis in #5042
- Move task-specific guidance out of root
CLAUDE.mdby @strickvl in #5049 - Trim Codex agent instructions by @strickvl in #5050
- Fix duplicated word in service connector login output by @kounelisagis in #5046
- feat: added logging and otel support to helm charts by @amitvikramraj in #5048
- Support deleting artifact data from server API by @Json-Andriopoulos in #5034
- Fix dynamic pipeline step config race condition by @schustmi in #5053
- Fix broken docstring checks & instructions by @Json-Andriopoulos in #5058
- Updated docs to include K8s distros by @AlexejPenner in #5061
- fix: decouple the zenml logging level setting from ZENML_DEBUG env var by @amitvikramraj in #5062
- Always track pipeline image when using skip_build=True by @schustmi in #5069
- Improve DAG endpoint performance by @schustmi in #5051
- Fix truncated dashboard URLs in CLI output by @kounelisagis in #5045
- Dynamic pipeline start ordering by @schustmi in #4995
- Allow requesting extra step metadata in dag endpoint by @schustmi in #5070
- Narrow exception handling in list projects CLI to RuntimeError by @qubeena07 in #5074
- feat: bumped otel version to support fastapi 0.138.0 version by @amitvikramraj in #5060
- Allow passing raw values as step parameters in dynamic pipelines by @schustmi in #5079
- Dynamic pipeline improvements by @schustmi in #5052
- Fix/mlflow model registry crash by @Json-Andriopoulos in #5072
- Fix SSH orchestrator container name collisions on pipeline re-runs by @kounelisagis in #5082
- In-process execution caching by @schustmi in #5038
- Add DigitalOcean integration (Spaces artifact store, DOCR container registry) by @htahir1 in #5054
- Add project metadata by @strickvl in #5086
- Prepare release 0.96.2 by @github-actions[bot] in #5092
New Contributors
- @kounelisagis made their first contribution in #5031
Full Changelog: 0.96.1...0.96.2