Prefect 2.8.7 is here with enhanced concurrency handling & engine reliability, a new flow run graph, and more!

Prefect 2.8.7

Our latest release introduces improved concurrency handling, flow run graph enhancements, and result artifacts, elevating the Prefect experience. We’ve made major improvements to the Prefect engine, supporting mixed asynchronous and synchronous code, closing long-standing bugs, and ensuring reliability when running flows.

Key concurrency and engine reliability enhancements

  • Dedicated worker thread for flow and task orchestration.
  • Synchronous flows run on main thread, resolving issues like #5991.
  • Asynchronous flows have separate event loop from Prefect engine.
  • Flow timeouts enforced with signals for effective interruption of long-running calls.
  • Async flows callable from sync flows; async tasks usable as upstream dependencies for sync tasks.
  • Deadlocks prevented when waiting for many sleeping tasks or having large numbers of synchronous tasks.
  • Debug mode enables verbose logging from Prefect concurrency internals.
  • API limits to 100 concurrent requests with SQLite backend to avoid database contention.
  • Task input resolution no longer uses worker threads, preventing deadlocks with numerous upstream inputs.

Results tab on flow run pages

The Prefect UI now renders information about your flow run and task run results!

This view provides a visual representation of the output of your tasks and flows and, when possible, provides links to results persisted using any of our storage blocks. To see this in your UI, run any flow and navigate to the run page; from there you’ll see a new tab, “Results”:

Flow run graph

We heard that people loved the simplicity and sleekness of the timeline on the flow run page, but valued the radar graph’s ability to traverse between flow runs and subflows runs. This release introduces the ability to expand and collapse subflow runs within the timeline. With these enhancements, the flow run timeline has now evolved into a general purpose flow run graph, with the ability to render thousands of nodes and edges performantly. The radar graph has been retired. You can now observe and explore your flow runs even more quickly and easily in a single flow run graph!

Other Notable Changes


  • Reverse option for flow run logs CLI (#8625).
  • Full run history in UI (#8885).
  • Improved SQLite sync mode performance (#8071).
  • Support for variadic keyword arguments in (#8188).
  • Add and deployment.version to prefect.runtime (#8864).


  • Resolved issues with race conditions (#8886), configuration (#8872), and recursion limits (#8827).
  • Fixed state message display in flow run metadata panel (#8885).
  • Fixed prefect dev start failure (#8850).
  • Resolved image pull errors with certain cloud providers by changing Docker build configuration(#8889).

For additional information, view the complete release notes.


Congrats, the UI is a huge update! :tada:


This is a great update, which has made submitting more than ~1000 tasks much more stable and robust without using workarounds. The results tab is also a great feature, which allows you to easily see which task wrote to which cache file.

I will say that for our use case (a single flow with multiple sequential map tasks, mapped over thousands of keys, running on Ray), there are a few ways that the radar view has features that the timeline view cannot replace, so the radar view being retired means that we lose those features. For one, only tasks that have begun running or completed/failed/crashed somehow are shown; pending tasks are not shown whatsoever - not until they transition to running, which could be hours away. The radar view showed pending tasks, as well which upstream tasks that each pending task was waiting for.

Secondly, the hierarchical nature of the radar view is not retained with the timeline view; the “rings” of the radar were a useful way to visualise the stages of a flow. For example, with a flow with 3 sequential tasks (e.g. double, halve, triple) mapped across many thousands of items (e.g. a list of 1000 ints, each one being doubled, then the output halved, then the output tripled), each “ring” of the radar view collected all the map tasks of the same type (e.g. the first “ring” is all the double tasks, then the second “ring” is all the halve tasks, and the third “ring” is the all the triple tasks) - regardless of the actual order that the tasks ended up running in, which is what the timeline view is all about; since the x-axis of the timeline view is time, inherently it is grouping tasks by execution order. In general, the radar view grouped tasks based on task dependencies, which has advantages over the timeline view which groups tasks solely based on execution order (which can be arbitrary).

Thirdly, for a long-running flow that could take hours or days to complete, the timeline view (even in nearest parent layout - waterfall layout is worse) ends up being a very, very, very thin and long graph (it is this shape because you may have thousands of tasks - but with only, say, 32 CPUs, Ray can only schedule 32 tasks to run in parallel at once, so you end up with a graph that is 32 tasks high, where each task is a very long bar, stacked left-to-right hundreds or thousands of times) is really not space-efficient at all. For example, even with the task dependency arrows, you may be scrolling left or right for a very long time before you find a task’s upstream or downstream tasks. The radar view is the same shape regardless of how little or much time the tasks take to run, and having a view that is independent of running time is highly beneficial.