Docs
Reference

Run Concurrency

Breyta flow run concurrency reference for controlling overlap, per-key execution, and version handoff behavior.

Quick Answer

Flow run concurrency is controlled by :concurrency on the flow definition:

  • choose model: :singleton or :keyed
  • choose version policy: :supersede, :drain, or :coexist

This is run-level behavior (between workflow executions), not per-step execution shaping.

Config Shape

FieldRequiredValuesNotes
:typeYes:singleton, :keyedDefines run isolation model.
:on-new-versionYes:supersede, :drain, :coexistDefines behavior when a new released version starts receiving runs.
:key-fieldFor :keyedkeyword or path vectorExtracts run key from input (for example :order-id or [:event :id]).

Model Behavior

ModelWhat is uniqueTypical use
:singletonOne active run slot per flow slug/workspaceScheduled rollups, singleton workers, periodic sync jobs
:keyedOne active run slot per key valueEntity/event scoped flows (order, user, ticket, webhook event)

Version Handoff Policy

:on-new-versionBehaviorUse when
:supersedeRunning older-version executions are terminated and new version runs immediately.Fast cutover is more important than finishing in-flight work.
:drainRunning older-version executions finish first; new version runs wait.In-flight work must complete before cutover.
:coexistOlder and newer versions can run at the same time.Parallel transition is acceptable and version overlap is intentional.

Canonical Examples

;; One active run at a time; cut over immediately on release.
{:concurrency {:type :singleton
               :on-new-version :supersede}}

;; One active run per order id; drain old version before key-wise cutover.
{:concurrency {:type :keyed
               :key-field :order-id
               :on-new-version :drain}}

Practical Guidance

  1. Start with :singleton unless you explicitly need per-entity parallelism.
  2. Use :keyed only when every invocation/interface/schedule path reliably supplies the key field.
  3. Pick :drain when side effects must finish before version change.
  4. Pick :supersede for incident fixes/hot releases where immediate behavior change matters.
  5. Use :coexist deliberately and monitor version mix in runs after release.
  6. For public or paid installed apps with a manual run page, do not use
    :supersede unless "new run replaces old run" is intentional user-facing
    behavior. If users should be able to start another run while a previous run
    remains visible or continues working, prefer :coexist.

Common Mistakes

  • Confusing flow run concurrency with per-step retries/timeouts (different scope).
  • Choosing :keyed without ensuring input always contains the key field.
  • Changing version policy without validating overlap behavior for each invocation/interface/schedule path.
  • Treating "only the latest installed-app run is visible" as a UI bug before
    checking whether :singleton :on-new-version :supersede intentionally caused
    the earlier run to be replaced.

Related

As of Jun 15, 2026