Skip to content

CONCEPT Cited by 1 source

Back-dirty (feedback-loop invalidation)

A back-dirty is a feedback-loop pattern in a multi-system reactive runtime where a later-running system invalidates work done by an earlier-running system, forcing the earlier system to re-run and potentially re-invalidating the later system, potentially oscillating until a fixed point.

The term is Figma's (Source: sources/2026-04-21-figma-rebuilt-foundations-of-component-instances):

"Running updates in a predictable order surfaced hidden feedback loops, where later systems would invalidate work done by earlier ones and force them to re-run. We call these patterns 'back-dirties.' Making them explicit helped us eliminate many of them and move closer to a more unidirectional flow, where source-of-truth changes trigger all relevant side effects across our various systems in a predictable way."

The anti-pattern

Consider a client with N reactive subsystems — layout, variable resolution, constraint enforcement, instance materialization, rendering. Each processes changes by reading some state and writing other state. If the order in which they run isn't disciplined, subsystem j (run after i) may write to state that i reads; on the next tick, i runs again, writes state j reads, and the loop churns until it incidentally stabilizes or visibly oscillates.

Before Figma's runtime-orchestration unification, "each runtime system managed its own updates and scheduled itself in ad hoc ways, which made side effects hard to reason about." The consequence named in the post: "different systems would 'fight' over the same subtree, repeatedly invalidating each other."

Why ad-hoc runtimes produce back-dirties

Three structural causes:

  1. Independent scheduling. Each subsystem schedules itself when it notices it has work. No cross-system ordering contract → no guarantee that subsystem deps run first.
  2. Undeclared cross-system deps. Subsystem j depends on subsystem i's output, but nothing in the code says so. The dep is latent.
  3. Mutable shared state. Both subsystems write to the same document nodes. Absent ordering, writes interleave.

Fix shape: collapse scheduling into a shared orchestration layer that runs subsystems in a predictable order (topologically sorted by inter-system deps), so each subsystem's inputs are stable by the time it runs.

Detection

The fix that enabled Figma to see back-dirties:

"As we unified these runtimes under a common framework, we gained something just as valuable as efficiency: visibility. Running updates in a predictable order surfaced hidden feedback loops."

Predictable ordering acts as a diagnostic substrate: if subsystem i has to re-run after subsystem j in the same tick, that's a back-dirty. In the ad-hoc scheduling regime the pattern was noise in the perf trace; under orchestrated ordering it's a discrete signal.

Elimination

Named in the post: "Making them explicit helped us eliminate many of them and move closer to a more unidirectional flow."

The end state — unidirectional flow — is the same shape as Redux / Flux reducers, spreadsheet recalc DAGs, and pipelined CPU stages: a strict topological sort of subsystems such that data flows source-of-truth → subsystem₁ → subsystem₂ → … → rendered output, never backward.

Practical elimination tactics (derivable, not all named in the post):

  • Compute-vs-write phase split. Subsystem i writes to an intermediate buffer; subsystem j reads from i's buffer, not from the document directly. i's outputs are stable by construction.
  • Push deps upstream. If j keeps invalidating i, move j's input computation into i's phase.
  • Demote a writer. If two subsystems write the same property, pick one owner; the other becomes a reader with a read-only projection.
  • Cycle / oscillation in CSS layout engines — e.g. scrollbar appearance changing the viewport width which changes layout which changes scrollbar presence. Browsers add tie-breaking rules to prevent oscillation.
  • ECS systems in game engines — strict scheduling of system execution order in a per-frame topological sort prevents the same failure mode.
  • Kubernetes controller "level-triggered" reconcile — if controller A's write triggers controller B's write which triggers controller A again, the cluster oscillates; resolved by write-idempotency + reconcile budgets.
  • Build systems with mutual dependencies — Bazel's requirement that the dep graph be a DAG; cycles detected at load time and refused.

Not addressed in Figma's post

  • How back-dirties were enumerated before elimination.
  • How many existed / how many are now eliminated.
  • Which specific subsystem pairs had them.
  • Whether the new orchestration prevents new back-dirties statically or relies on eternal vigilance.

Seen in

Last updated · 200 distilled / 1,178 read