I've recently done a comparison between these three, although I only had to justify it to myself so I didn't do anything particularly formal. My overall conclusion was that the way dagster handled software-defined assets was a huge benefit over previous work we had done with airflow. The main points of differentiation:
• airflow pushed as towards a workflow that pushed everything into a single task, so we really weren't using the DAG capabilities. This mostly stemmed from our need to pass large amounts of data between processes, which airflow doesn't handle - hence we would have to either handle intermediate storage ourselves or end up with behemoth tasks (we chose the latter).
• resource usage - dagster easily used less resources than airflow - granted we had done only minimal tuning to airflow, but memory usage was a bit of an issue
• there is a much better test workflow from within dagster - we found testing/debugging significantly harder with airflow
• I only delved minimally into prefect, but comparing prefect and dagster, the way that dagster managed partitioning was more aligned with what we were looking for, and more capable.
• the only point that dagster lost out on was the name - in Australia (and growing up on a sheep farm), the word dag has a slightly unsavoury meaning 😄