Prefect 3.8.6 was published on 14 September 2026. A paused flow run can now move to cancelling, including a blocking pause after its timeout elapses. GitHub marks the tag as a stable release.
The full release notes and downloads are on the GitHub release page. The compare from 3.8.5 to this tag is the full changelog.
Cancellation from a paused state ¶
Cancel against a paused flow run is the change this tag is named for. #23039 allows the transition from paused to cancelling. Until this patch, cancel had no move from paused onto cancelling, so the run stayed there until some other transition fired.
#23064 covers a blocking pause after its pause timeout elapses. The timeout and the cancel stay separate events. The timeout alone leaves the run paused. Cancel after the timeout now has a legal transition.
Alerts that only match completed, failed, or crashed miss these runs. The release adds no setting to disable the transition.
#23043 allows flow names with surrounding whitespace to complete. A name with a leading or trailing space could finish the work and still fail completion. Stored names are not described as trimmed on write.
Recorder inserts and history queries ¶
Task run writes and history grouping are the database changes worth measuring. #23041 reduces task run recorder INSERT compilation CPU. The recorder compiles an insert for task run rows. On an API process that records many short tasks, that cost is CPU while the statement is built. If recorder CPU was hot, compare the same flow on 3.8.5 and 3.8.6.
#22879 buckets run history with arithmetic instead of a range join. Arithmetic assigns the bucket from the timestamp. Recount a known window after the upgrade. A row on a bucket boundary can land in a different bucket, and the notes list no compatibility flag for the old join.
#23080 scans orphaned logs and artifacts by a flow_run_id cursor instead of an anti-join on every batch. The cursor walks child rows in flow_run_id order. The batch anti join probed the parent flow run table on every page. Cost follows the flow_run_id index.
#23033 rebuilds an invalid ix_event_resources__occurred left by an interrupted build. A killed index build can leave the index invalid, and the planner then ignores it for event resource lookups. Check that index after upgrade if a migration died mid build.
SQLite locks and the storage default ¶
SQLite installs, the ones not pointed at Postgres, pick up three operational fixes.
#22967 fixes the database locked error when marking deployments ready. #23052 begins the SQLite write transaction in mark_deployments_ready before the read, so the read and the update share one transaction. A read followed by a separate write returns database locked when another connection takes the writer between the two statements. Other writers now wait through the read. That wait beats a failed ready mark.
#23056 schedules automation cache updates on the event loop for SQLite. The cache write stays on the loop that owns the connection. A busy API loop postpones those updates.
#23070 defaults local_storage_path to PREFECT_HOME/storage. An explicit value still wins. The notes list no copy of files already written somewhere else. After the first run on 3.8.6, check where new results and deployment storage appear.
Workers, the Azure CLI, and docs ¶
Process checks and shell lookup changed for Windows and for Azure. #23037 treats ERROR_ACCESS_DENIED as alive in the Windows helper _is_pid_alive. Access denied means the process handle could not be opened. It is not an exit. Reading it as dead lets the engine treat a live pid as gone while the flow run is still executing. The other miss is a false alive after Windows reuses a pid the caller cannot query. The patch prefers a false alive.
#23035 resolves the Azure CLI executable through PATH in AzureCLI.run_command. A missing az fails that lookup. Images that only put az on PATH pick up the fix with no new setting.
#23067 fixes Docker work pool editing and block and env serialization in UI v2.
#23028 documents Backoff Limit and PREFECT_FLOW_RUN_EXECUTE_SIGTERM_BEHAVIOR in the Kubernetes guide. Backoff Limit caps pod restarts. The setting names what the flow run does on SIGTERM. #23077 explains commit_mode in the transactions guide.
The remaining items are maintenance. #23030 adds a TLA+ model for deployment concurrency leases. #23058 and #23059 move the old SQLite Dockerfile and its UI builders from Debian Bullseye to Bookworm. Rebuild that legacy image if you still publish it. #23009 updates tornado from 6.5.7 to 6.5.8.
Upgrade notes ¶
Paused runs can enter cancelling, including a blocking pause after the pause timeout. Update any state client or alert that assumed a paused run stayed paused until resume.
local_storage_path defaults to PREFECT_HOME/storage when unset. Confirm the directory is writable and that new files appear there.
SQLite servers that log database locked from mark_deployments_ready should take this patch. The write transaction starts before the read, so other writers on that file wait instead of failing the ready mark.
The legacy SQLite image base moves from Bullseye to Bookworm. tornado 6.5.8 replaces 6.5.7, so a lockfile that pins the previous wheel needs an update. The release notes list no schema migration.
Where to get it ¶
- GitHub release page for tag 3.8.6
- Repository PrefectHQ/prefect
- Tag
3.8.6