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_acceleratoris 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_acceleratorsentry such asnvidia_gpu=64now 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_policycounts 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 --queueandflyte.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 CLUSTERlists a cluster’s node groups with capacity types, weight, and limits.-of jsonaddsmax_pods.flyte update node-groupsedits node groups on self-managed clusters, in$EDITORor 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 --mountcreates and mounts a volume in one step, without--bucket.flyte status volume,flyte unmount volume, andflyte forget volumemanage local mounts.forgetrefuses to discard unpublished work without--discard.flyte warmup volumefills the local cache for offline use.--artifact NAME [--version V],--run/--action, or--locatornames the volume to mount.--project,--domain, and--regionwork 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 whenboto3is installed. Repeated promotions into the same destination copy only new chunks, andpublish_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.AppEnvironmentaccepts a pod template whose primary container is not namedapp, sopod_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
slurmtask runs its container image as an sbatch job under Pyxis/Enroot, with typed inputs and outputs, caching, retries, and error reporting. Removeplugin_configand the same task runs on Kubernetes. - A
slurm_scripttask 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-dbtaddsDbtTask, 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 asDbtNodeResultsummaries.flyteplugins-nextflowruns a Nextflow pipeline inside a Flyte task withrun_nextflow("nf-core/demo", ...)andnextflow_image(). Each Nextflow task appears as its own child action.GitLabProvider, in the newflyteplugins-gitlabpackage, 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.
ModelStreameroffersstream(),state_dict(), andload_into(module).load_hf_model(path, device="cuda")loads a Hugging Face model and returns(model, path).load_format="flyte-streaming", inflyteplugins-vllm, streams weights into an offlinevllm.LLMinside 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/decisionstakes 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 acurlexample. - 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=...)inflyteplugins-union[guardrails]turns a Python function into a guardrail app. ReturnVerdict.allow(),Verdict.block(message, reason), orVerdict.cached(content), and useguardrail_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=VALUEand--custom-context-from-env VARset 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.jsonworks with credential-helper configs, such as cross-account Amazon ECR.File.from_local,Dir.from_local,storage.put, andstorage.put_streamtakechunk_sizeandmax_concurrency, with defaults fromFLYTE_IO_UPLOAD_CHUNK_SIZEandFLYTE_IO_UPLOAD_MAX_CONCURRENCY.batch_sizeis honored on S3, GCS, and Azure, which helps avoid S3 SlowDown errors.flyte.init_from_api_key()takesca_cert_file_pathandinsecure_skip_verify, for API keys behind TLS-inspecting proxies.- Set the image builder to
local-podmanto build images with Podman. - GPU names:
RTX_PRO_4500and"RTX_PRO_6000:2"can be requested by name.- RTX PRO 6000 MIG profiles (
1g.24gb,2g.48gb,4g.96gb) can be requested withflyte.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_typesconstraints, titles, descriptions, andjson_schema_extracarry into a task’s JSON schema. Discriminated unions andAnnotatedenums work. DO_NOT_TRACK=1orFLYTE_DISABLE_TELEMETRY=trueturns 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 ofActionDetailsandRunDetails,Artifact.to_python(), andTrigger.get_details()can be called withoutawait. Awaiting a synchronous remote method, such asawait details.outputs(), is deprecated in favor of.aio(); it still works and raises aDeprecationWarning.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 gettables fit narrow terminals. flyte.sandbox(alpha) is deterministic: reading the clock, unseededrandom, andos.urandom()raise inside it, and sleeps count against the timeout.asyncsshmoves to theflyte[ssh]extra. The default image still includes it, and other images install it when a debug session starts.ContainerTaskandflyte.extras.shelltasks withcache="auto"now include the image, command, and arguments in their cache version.flyte get queuefits the terminal and points to-of jsonfor the columns it drops. A limit of 0 reads as unlimited, and a queue with no scheduling policy reads asunspecified.flyteplugins-unionversions:- Flyte SDK 2.11 and 2.12 need
flyteplugins-union0.18.0 or later, and SDK 2.12.2 needs 0.20.2 or later. With an older plugin,flyteplugins.union.remotefails to import, which breaksflyte debugand 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
flyteon 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.
- Flyte SDK 2.11 and 2.12 need
🔧 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.mapaborts 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 markedCache-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.FileandDirno 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-keyno 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.enableddefaults totrue. Zero trust needssecrets.adminenabled; withsecrets.admin.enable: falsethe chart fails to render.- If you host your own control plane, set
zero_trust.enabled: falsebefore upgrading. Zero trust is not supported for self-hosted control planes. - If your data plane still uses the
knative-operatorpath, run theknative-migrationchart before upgrading; skipping it deadlocks the upgrade. Then setgateway.enabled: trueandknative-operator.enabled: false.
- If you host your own control plane, set
- 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 overrideprometheus.server.extraFlags, add that flag along withweb.enable-lifecycleandenable-feature=expand-external-labels, or append flags withprometheus.server.extraArgsinstead. - 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
flyteconnectorimage that includes the BigQuery, Snowflake, Databricks, Spark, and Slurm connectors, so you no longer need to overrideflyteconnector.imageto use them. telemetry.enabled: false, which setsDO_NOT_TRACK=1on every task pod and turns off the SDK’s crash reports and usage counts. See Telemetry.- Opt-in Nydus lazy image pulls: set
nodeBootstrap.enabledand thenimageBuilder.enableImageOptimizationto pull images lazily, as BYOC data planes do. See the chart’s release notes for node requirements.
⚠️ 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=64now 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_acceleratorif untyped requests should count as a specific type.
- Add a per-model entry, for example
- 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. asyncsshis not installed withflyte(SDK 2.12.2). SSH debugging on images that can’t reach a package index, such as air-gapped images, needsflyte[ssh]in the image.- Container and shell task caches miss once (SDK 2.12.0). Entries for
ContainerTaskandflyte.extras.shelltasks withcache="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, andUNION_VOLUME_METADATA_STORE. Volumes cannot be mounted on Windows in this release. flyte mount volumenames the volume with a flag (plugin 0.19.1). Use--artifact,--run/--action, or--locator.--keep-artifactis replaced by--detach-artifact.--fairnessis removed from queues (plugin 0.16.0). Removeflyte create queue --fairness, thefairnessedit key, andQueue.fairness, and use--schedulinginstead.max_nodes: 0means 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-union0.18.0 or later, and SDK 2.12.2 needs 0.20.2.