Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Concurrency, Parallelism, and Frame Budgets

Concurrency modelConflict-aware executionRevision 78002f6

Bevy has three distinct forms of concurrency.

Parallel schedule execution

The multithreaded executor combines two graphs:

  • dependency edges say what must finish first;
  • component/resource access says what may safely overlap.

Query<&Position> can run beside another reader. Query<&mut Position> conflicts with both. Disjoint filters may allow more precise compatibility. Ready systems execute on ComputeTaskPool; completion events unlock dependents.

Parallel iteration inside one system

A system can use parallel query iteration when one system owns the relevant access but the entity set can be partitioned safely. This is nested data parallelism, distinct from running several systems.

Background async work

Assets use IoTaskPool; longer async computation has AsyncComputeTaskPool. These tasks may outlive a frame and return owned results or update thread-safe service state. They must not retain ordinary world borrows across suspension.

Barriers are deliberate

Exclusive systems, non-Send parameters, dependencies, and ApplyDeferred reduce parallelism because they protect real invariants. A faster schedule that observes half-applied entity structure would be incorrect.

The scheduler therefore optimizes a constrained problem:

maximize ready compatible work
subject to dependency, access, thread-affinity, and mutation barriers

Frame latency also matters more than aggregate throughput. An unbounded system or background-result integration step can still miss the frame budget even if all memory access is safe.