Fairer queue scheduling, cluster health from pods, scale-to-zero reusable environments, local volumes, and Slurm, dbt and Nextflow integrations.

October 2026

⚙️ Fairer Queue Scheduling

A strict_fifo queue whose first action is waiting for resources now reserves only what that action needs, and keeps that reservation until the action fits.

  • Work from other queues that fits in the remaining room keeps running, so CPU-only work runs beside an action waiting for a GPU.
  • A same-priority queue can no longer take every freed slot ahead of the waiting action.
  • Higher-priority queues are never held back.

GPU caps and accounting now follow the GPU model a task actually runs on:

  • A task that requests GPUs without naming a model runs on the accelerator the scheduler counted it against, so queue GPU caps and cluster usage match where the pod lands.
  • If task_resource.default_accelerator is set, such a task is pinned to that type. Ray head and worker groups are pinned the same way.
  • A device or MIG partition that a task names is kept as written.
  • Untyped GPU requests count as “any NVIDIA GPU” instead of T4, unless a default accelerator is set. Untyped TPU, Neuron, AMD, and Gaudi requests count under their own class.
  • A class-only max_accelerators entry such as nvidia_gpu=64 now caps GPUs requested without naming a model. Requests that name a model count against that model’s entry (see Breaking Changes below).
  • A Ray task with reuse_policy counts against queue caps once per environment, head plus workers, instead of once per action.

See Resource caps and scheduling.

🔍 Live Queue Activity

Queue details gain an Actions tab that lists the queue’s pending and in-flight actions across runs, live, with each action’s phase and how long it has been queued. You can search, open an action, or abort it if you have permission.

  • The Overview tab shows Waiting depth separately from Total depth.
  • Run details show the queue each action ran on, not only the run’s default.
  • Rerunning or debugging an action uses that action’s queue.
  • The launch form lets you choose a different queue when you rerun.

See Managing queues.

🌐 Runs Follow Their Queue Across Cluster Pools

With flyte run --queue, the code bundle, inputs, and image builds go to the queue’s cluster pool, so a run on a queue in another pool or cloud finds its data.

  • flyte deploy --queue and flyte.deploy(queue=...) are new.
  • Reruns and trigger runs re-upload inputs when the queue changes.
  • Artifact-trigger runs launch on the trigger’s queue.

A run whose inputs or code bundle are in a different cluster pool than its queue is now rejected at submission. The error names the fix: run on a queue in the right pool, or redeploy with --queue. The Console launch form shows the same guidance. Previously these runs failed inside the task pod.

Requires Flyte SDK 2.12.2.

See Cluster pools.

⚙️ Cluster Health From What Is Running

Every cluster component now gets a status from its own pods, including components with no health check of their own. A component is Unhealthy when:

  • A pod is crash looping.
  • A pod has been not ready for 5 minutes.
  • The component should have pods but has had none for 5 minutes.

A workload scaled to 0 makes its component Unhealthy at once. A crash-looping pod is reported as a crash loop, with its restart count and last exit, instead of “pods not ready”.

These no longer mark the cluster Degraded:

  • Isolated connector probe failures.
  • Dependency checks that fail while a component restarts.
  • Routine plugin operator rollouts.
  • Stopping a connector app.

Sustained failures are still reported. When a cluster stops reporting, it shows Unhealthy with the time of its last report, and the details page marks its snapshot and Components tab as stale.

📊 Redesigned Cluster Details

The Components tab groups workloads and health checks by category and lists tunnels with their connection state. Its details drawer shows resource requests and limits, replicas, pod diagnostics, configuration, and plugin dashboards. Data already loaded stays on screen if the live connection drops.

Each component and pod shows whether its configuration is current, rolling out, or needs a restart to pick up a change, with the time the configuration last changed.

A new Node pools tab shows each node pool’s node and pod availability and its resource and accelerator usage next to its configured scaling. A read-only drawer shows capacity type, shapes, taints, and labels.

Cluster CPU and memory now describe the cluster itself. These figures previously came from project quotas.

  • Used is the total requests of the pods running on the cluster.
  • Capacity is the ceiling its node groups declare.

The details page also shows reported software versions, region, storage configuration, log-link settings, and connector resource requests, each with a copy action. Client secrets in a cluster’s configuration show as <redacted> in the Console and the API.

From the CLI:

  • flyte get node-groups CLUSTER lists a cluster’s node groups with capacity types, weight, and limits. -of json adds max_pods.
  • flyte update node-groups edits node groups on self-managed clusters, in $EDITOR or from a file. It requires cluster-management permission.

See Clusters.

♾️ Reusable Environments Scale to Zero

An environment declared with replicas=(0, N) starts with no replicas, scales up to N with demand, and removes idle replicas after scaledown_ttl. Previously the pool was created at its maximum size.

Replica management is also more reliable:

  • Idle replicas are reclaimed even while another task is still registered on the environment.
  • Very large environments clean up idle replicas on time.
  • An environment no longer drops below its minimum after idle replicas are removed.
  • Workers are no longer removed while tasks are queued for, running on, or finishing on them. This fixes “Reusable worker … was unexpectedly disconnected” errors.

A retried task in a reusable environment reuses its completed sub-actions.

See Reusable containers.

💾 Volumes on Your Laptop

flyte mount volume uses NFS on macOS, so you don’t need macFUSE. It forks by default, and Ctrl-C commits the fork; use --read-only, --no-commit, or --transport fuse|nfs to change that.

The local working copy is durable, and the next flyte mount volume picks up unpublished local work, even offline.

  • flyte create volume NAME --mount creates and mounts a volume in one step, without --bucket.
  • flyte status volume, flyte unmount volume, and flyte forget volume manage local mounts. forget refuses to discard unpublished work without --discard.
  • flyte warmup volume fills the local cache for offline use.
  • --artifact NAME [--version V], --run/--action, or --locator names the volume to mount.
  • --project, --domain, and --region work with both mount and explore.

Missing credentials fail in under a second, and AWS SSO profiles are resolved.

See Work with a volume on your machine.

💾 Copy, Release, and Inspect Volumes

New Volume methods copy and release volumes, and run details show the volumes, files, and directories in a run’s inputs and outputs.

  • Volume.clone(destination, ...) copies a volume server-side within a bucket on S3, GCS, and Azure, and between S3 buckets when boto3 is installed. Repeated promotions into the same destination copy only new chunks, and publish_artifact= registers the copy as an artifact version.
  • Volume.abandon(timeout=30) releases a mount whose client died, without committing, so the pod can remount.
  • AppEnvironment accepts a pod template whose primary container is not named app, so pod_template=allow_volumes() mounts volumes in apps without elevated privileges.
  • Volumes now mount on EKS Auto Mode clusters that Union provisions for self-serve organizations.
  • Run details show volumes, files, and directories in a run’s inputs and outputs as cards with size, storage location, and read-only or read-write mode. Every path has a copy button, and a volume input links to the run that produced it.
  • Block volumes run the first trim after a mount in the background, throttle later trims, and bound the volume client’s memory. This roughly halves peak memory at checkpoints and reduces out-of-memory kills.

See Volumes.

🚀 Run Tasks on Slurm

flyteplugins-slurm runs Flyte tasks on an existing Slurm cluster, including Soperator-managed clusters, with no changes to the cluster.

  • A slurm task runs its container image as an sbatch job under Pyxis/Enroot, with typed inputs and outputs, caching, retries, and error reporting. Remove plugin_config and the same task runs on Kubernetes.
  • A slurm_script task submits an existing sbatch script unchanged.

The connector runs in the data plane’s flyteconnector image and reaches the cluster over SSH to a login node.

See Slurm.

✨ dbt, Nextflow, and GitLab Integrations

Three plugin packages add dbt, Nextflow, and GitLab integrations.

  • flyteplugins-dbt adds DbtTask, which runs a dbt CLI invocation as a Flyte task. The command, selection, target, and extra arguments are task inputs, so one task serves several commands. Results come back as DbtNodeResult summaries.
  • flyteplugins-nextflow runs a Nextflow pipeline inside a Flyte task with run_nextflow("nf-core/demo", ...) and nextflow_image(). Each Nextflow task appears as its own child action.
  • GitLabProvider, in the new flyteplugins-gitlab package, joins the GitHub, Slack, Linear, ClickUp, and Jira webhook providers. It verifies GitLab’s shared token and normalizes deliveries into typed events.

See dbt, Nextflow, and GitLab.

🏷️ Pin a Trigger to a Task Version

flyte.Trigger(name="prod", task_version="v1.4.0") keeps a trigger on that task version when other versions are deployed. To promote or roll back, change the pin and redeploy. Triggers without a pin keep following each deploy.

Requires Flyte SDK 2.12.5.

See Triggers.

⏳ LLM Serving Metrics and Model Streaming

On BYOC clusters, the app details page for vLLM and SGLang apps charts Time to First Token, Time per Output Token, and generated tokens per second.

flyte.extras.model_streamer streams safetensors weights from object storage as parallel byte ranges, with nothing written to local disk.

  • ModelStreamer offers stream(), state_dict(), and load_into(module).
  • load_hf_model(path, device="cuda") loads a Hugging Face model and returns (model, path).
  • load_format="flyte-streaming", in flyteplugins-vllm, streams weights into an offline vllm.LLM inside a task.

See Stream model weights.

🤖 Inference Gateway Updates

The Inference Gateway, in preview, adds a decisions endpoint, a Google Vertex AI provider, and Python guardrails.

  • Decisions. POST /v1/decisions takes a state and named questions and returns typed answers: a probability, a chosen option, or a score. Providers can be TypeSafe models (a new hosted provider), hosted LLMs, or Union-served vLLM and SGLang apps with Answers decisions turned on. The gateway overview gains an Endpoints card with a curl example.
  • Google Vertex AI. The provider takes a GCP project and region, and either a Union secret holding a service-account key or the gateway’s own Google identity. Call its models as vertex/<model>; budgets and spend are tracked as for other providers.
  • Python guardrails. GuardrailAppEnvironment(name=..., pre=..., post=...) in flyteplugins-union[guardrails] turns a Python function into a guardrail app. Return Verdict.allow(), Verdict.block(message, reason), or Verdict.cached(content), and use guardrail_router() to add the routes to an existing FastAPI app.

Existing gateways show “update available” until they are redeployed.

See Inference Gateway and Python guardrails.

✨ Edit Deployment Values in the Console

For self-serve organizations, a cluster’s Config tab has a values.yaml editor. Browse and link to deployment revisions, edit and apply values, and watch deployment progress and errors.

The editor warns about unsaved changes, asks before overwriting a newer revision, and keeps your draft if a deployment fails.

🔧 SDK Updates

  • flyte run --custom-context KEY=VALUE and --custom-context-from-env VAR set a run’s custom context, for file tasks, --local, --tui, and deployed tasks.
  • @env.task(prefix=...) names a task <env>.<prefix>-<function>, so one environment can hold same-named functions. Defining two different functions under one task name logs a warning.
  • flyte create secret --type image_pull NAME --from-file ~/.docker/config.json works with credential-helper configs, such as cross-account Amazon ECR.
  • File.from_local, Dir.from_local, storage.put, and storage.put_stream take chunk_size and max_concurrency, with defaults from FLYTE_IO_UPLOAD_CHUNK_SIZE and FLYTE_IO_UPLOAD_MAX_CONCURRENCY. batch_size is honored on S3, GCS, and Azure, which helps avoid S3 SlowDown errors.
  • flyte.init_from_api_key() takes ca_cert_file_path and insecure_skip_verify, for API keys behind TLS-inspecting proxies.
  • Set the image builder to local-podman to build images with Podman.
  • GPU names:
    • RTX_PRO_4500 and "RTX_PRO_6000:2" can be requested by name.
    • RTX PRO 6000 MIG profiles (1g.24gb, 2g.48gb, 4g.96gb) can be requested with flyte.GPU(..., partition=...).
    • "T4 shared", "L4 shared", "A10G shared", "A10 shared", and "L40S shared" request a time-sliced share of one GPU.
    • Canonical accelerator names now use underscores, such as A100_80G. Space-separated names such as "A100 80G" are deprecated.
  • Pydantic Field(pattern=...), Field(ge=..., le=...), annotated_types constraints, titles, descriptions, and json_schema_extra carry into a task’s JSON schema. Discriminated unions and Annotated enums work.
  • DO_NOT_TRACK=1 or FLYTE_DISABLE_TELEMETRY=true turns off the SDK’s crash reports and usage counts.
  • Task error messages include the exception type, for example KeyError: 'price' instead of 'price'.
  • Action.details(), Action.wait(), the input and output methods of ActionDetails and RunDetails, Artifact.to_python(), and Trigger.get_details() can be called without await. Awaiting a synchronous remote method, such as await details.outputs(), is deprecated in favor of .aio(); it still works and raises a DeprecationWarning.
  • PodTemplate(labels={...}) works without a pod spec, for example to set a Kueue queue name.
  • The CLI loads about three times faster, and local runs and no-op tasks start about 100 ms sooner. Task pods skip build, deploy, and dataframe imports unless a task uses them. flyte get tables fit narrow terminals.
  • flyte.sandbox (alpha) is deterministic: reading the clock, unseeded random, and os.urandom() raise inside it, and sleeps count against the timeout.
  • asyncssh moves to the flyte[ssh] extra. The default image still includes it, and other images install it when a debug session starts.
  • ContainerTask and flyte.extras.shell tasks with cache="auto" now include the image, command, and arguments in their cache version.
  • flyte get queue fits the terminal and points to -of json for the columns it drops. A limit of 0 reads as unlimited, and a queue with no scheduling policy reads as unspecified.
  • flyteplugins-union versions:
    • Flyte SDK 2.11 and 2.12 need flyteplugins-union 0.18.0 or later, and SDK 2.12.2 needs 0.20.2 or later. With an older plugin, flyteplugins.union.remote fails to import, which breaks flyte debug and the Union CLI commands.
    • Plugin 0.18.0 is the first release that installs alongside SDK 2.11 and 2.12, and it no longer downgrades flyte on install. Releases 0.15.2 through 0.17.0 require SDK below 2.11.
    • Plugin 0.15.5 was published only for Linux x86_64, and other platforms resolve to 0.15.3, so upgrade to 0.18.0 or later.

🔧 Reliability and Fixes

Runs and logs

  • A run input or output with a large string value shows a compact, labeled preview, with copy and download for the full value.
  • Runs with more than 200,000 actions show accurate phase counts that update every few seconds.
  • A cached action shows which run, action, and attempt its result came from, with a link.
  • Task logs for completed or evicted pods that the node has already removed load from the cluster’s persisted logs, instead of failing with unable to retrieve container logs.
  • Logs for an older attempt no longer show a newer attempt’s output.
  • The logs tab stays live when you refresh or switch attempts.

Task execution and caching

  • A task sent to a worker right after another finished no longer waits about five minutes for the slot.
  • Cached outputs are copied within the object store, so many cache hits at once no longer exhaust a worker’s memory.
  • Reading a succeeded action’s outputs right after run.wait() no longer fails with NotFound for cache hits and retried actions.
  • flyte.map aborts in-flight children on failure, early exit, or cancellation, so runs no longer stay active.
  • When Kueue preempts a task’s pod, the task error shows Kueue’s reason instead of “object deleted”.
  • A cluster’s default pod templates now apply to Flyte 2 task pods, as they already did for Flyte 1 tasks.
  • Connector tasks resolve Union and Flyte secrets correctly again.

Platform

  • Running in an organization with no data plane says to connect one, instead of a generic “unavailable” error.
  • Registering a project no longer leaves a domain without its access policy.
  • An API request that names an organization other than the caller’s is rejected with PermissionDenied.
  • Authenticated responses from apps, the data plane, and the control plane are marked Cache-Control: private. Login redirects and authentication errors are marked Cache-Control: no-store.
  • The platform handles more concurrent task-coordination requests.
  • status.union.ai marks an API degraded or down only when a failure affects many organizations.
  • Images built with SDK 2.12.1 or later get updated CA roots. Rebuild images to pick them up.

SDK and plugins

  • A readmitted clustered task loads its own checkpoint.
  • Trigger list and dict inputs keep their element types.
  • File.download() skips the copy for local files.
  • File and Dir no longer take over custom-transformer blobs.
  • Remote builds through a localhost endpoint get a valid registry.
  • The threaded local cache no longer hits SQLite errors.
  • flyte debug --api-key no longer deadlocks.
  • The volume client no longer crashes on a canceled read, which had left block volumes returning I/O errors.
  • A second container in the same pod can mount a volume.

Console: sign-in and organizations

  • Sign-in and device authorization are one centered form. Going back to a sign-in link that was already used says so.
  • Creating an organization requires a work email, so onmicrosoft.com, Hotmail, and QQ Mail addresses are asked for a company address.
  • Returning users go to their last organization.
  • After an AWS Marketplace purchase, setup returns you to the linked organization.

Console: runs and navigation

  • Trace details show the trace name, the action ID, and a copyable link to the selected trace.
  • Actions restored by Recover have their own icon, and their cache tooltip shows cache disabled.
  • Links from run details to a queue or cluster return to the original run, action, and tab.
  • Settings links keep search and the selected cluster pool.
  • Entity pages show the entity’s name in the browser tab.
  • The Busiest Users dashboard shows names for shared apps and for runs created before a sign-in provider change.
  • Tabs use text labels.
  • The Apps card view has empty, loading, search, filter, and error states.
  • The action timeline stops counting at a terminal phase.
  • Opening one task group no longer opens another that shares its environment.
  • Restoring many run tabs no longer drives the browser to high CPU.
  • Live run views stay connected while many task versions deploy.

⚙️ Self-Managed Data Plane Updates

Update the Union dataplane Helm chart to 2026.11.0 or later. Before you upgrade:

  • Chart 2026.10.1 makes zero trust the default: zero_trust.enabled defaults to true. Zero trust needs secrets.admin enabled; with secrets.admin.enable: false the chart fails to render.
    • If you host your own control plane, set zero_trust.enabled: false before upgrading. Zero trust is not supported for self-hosted control planes.
    • If your data plane still uses the knative-operator path, run the knative-migration chart before upgrading; skipping it deadlocks the upgrade. Then set gateway.enabled: true and knative-operator.enabled: false.
  • Chart 2026.10.1 sets Prometheus’s Go memory limit from its container limit (enable-feature=auto-gomemlimit), so short spikes no longer kill it. If you override prometheus.server.extraFlags, add that flag along with web.enable-lifecycle and enable-feature=expand-external-labels, or append flags with prometheus.server.extraArgs instead.
  • Union workloads restart once on the upgrade to 2026.10.1, because their config checksum changes. Later changes to ConfigMap labels or template whitespace no longer restart them.

The upgrade brings:

  • Per-component cluster health from pods, named crash loops, fewer false alarms, secret redaction, and configuration rollout status. Until a data plane is upgraded, its components read “unknown”.
  • Reusable environments that scale to zero, release idle replicas promptly, and keep busy workers.
  • Untyped GPU tasks pinned to the type they were counted under, or to your default accelerator.
  • Logs for cleaned-up pods from persisted logs, and correct logs per attempt.
  • Faster task starts on a full worker, and cache hits that copy outputs within the object store.
  • Cluster default pod templates for Flyte 2 task pods, and Kueue preemption reasons in task errors.
  • On a data plane installed into one namespace: event details on task errors, cleanup of orphaned worker pods, and Ray cluster cleanup.
  • Fixed connector secrets, and a default flyteconnector image that includes the BigQuery, Snowflake, Databricks, Spark, and Slurm connectors, so you no longer need to override flyteconnector.image to use them.
  • telemetry.enabled: false, which sets DO_NOT_TRACK=1 on every task pod and turns off the SDK’s crash reports and usage counts. See Telemetry.
  • Opt-in Nydus lazy image pulls: set nodeBootstrap.enabled and then imageBuilder.enableImageOptimization to pull images lazily, as BYOC data planes do. See the chart’s release notes for node requirements.

See Upgrade the data plane.

⚠️ Breaking Changes

  • VS Code and Jupyter links into a task pod need run permission. These links run code with the task’s credentials, so opening one now requires permission to run executions in the project. Requests forwarded to the pod no longer carry your authorization header, identity headers, or Union session cookies. Spark, Ray, and Dask dashboard links still need only view access. Grant run permission on the project to users who need VS Code or Jupyter access.
  • Class-only GPU caps no longer cover requests that name a model. A class-only entry such as nvidia_gpu=64 now caps only GPUs requested without a model. Class-only entries for non-NVIDIA classes are rejected, and untyped GPU requests are no longer counted as T4. To adapt:
    • Add a per-model entry, for example nvidia-h100=8, for typed requests.
    • Name the device for non-NVIDIA caps.
    • Set task_resource.default_accelerator if untyped requests should count as a specific type.
  • Finished Flyte 1 task pods are deleted on BYOC clusters, as Flyte 2 task pods already were. To read finished-task logs, use the Console’s log links, which read persisted logs, instead of kubectl.
  • asyncssh is not installed with flyte (SDK 2.12.2). SSH debugging on images that can’t reach a package index, such as air-gapped images, needs flyte[ssh] in the image.
  • Container and shell task caches miss once (SDK 2.12.0). Entries for ContainerTask and flyte.extras.shell tasks with cache="auto" made before the upgrade miss one time. No action is needed.
  • Task error message text changes (SDK 2.12.2). Messages now start with the exception type. Code that matches on error text should match on the exception type, or update its pattern.
  • Badger is the only volume metadata store (plugin 0.18.0). Re-create volumes published with the SQLite or Redis metadata store, and remove uses of with_high_throughput_volume_deps, Volume.migrate_metadata_store_type, VolumeMigrateNoop, and UNION_VOLUME_METADATA_STORE. Volumes cannot be mounted on Windows in this release.
  • flyte mount volume names the volume with a flag (plugin 0.19.1). Use --artifact, --run/--action, or --locator. --keep-artifact is replaced by --detach-artifact.
  • --fairness is removed from queues (plugin 0.16.0). Remove flyte create queue --fairness, the fairness edit key, and Queue.fairness, and use --scheduling instead.
  • max_nodes: 0 means unbounded in node-group files (plugin 0.20.0). Where you used 0 to mean “unset”, remove the key or set the limit you want.
  • Upgrade the plugin with the SDK. SDK 2.11 and 2.12 need flyteplugins-union 0.18.0 or later, and SDK 2.12.2 needs 0.20.2.