Push-based vs. Pull-based Reactivity: The Two Driving Models Behind Fine-Grained Systems

Push-based vs. Pull-based Reactivity: The Two Driving Models Behind Fine-Grained Systems

Source: Dev.to

Core Idea ## Real-World Examples ## Push-based ## Pull-based ## Formal Definitions ## Timeline Diagrams ## Push-based ## Pull-based ## Pros & Cons ## How to Choose? ## Common Misconceptions ## “Pull means scanning the whole graph!” ## “Push always wastes computation.” ## “Push vs Pull is either/or.” ## “Why do even fine-grained systems still need Pull?” ## Conclusion ## Next Up Building on the previous article about the core ideas behind reactivity, this part clarifies the difference between Push-based and Pull-based reactivity models. In fine-grained reactivity: Let’s look at them through real-world analogies. Imagine ordering food in a food court. Now imagine buying a bubble tea. Key insight: Both models “push” signals — but Push pushes the computation, while Pull pushes the dirty mark. Note: even Pull-based systems still must walk the dependency graph during marking, but they do not recompute — they only set dirty = true. It depends entirely on the scenario. Modern reactivity libraries often combine both strategies. React is basically Pull + Scheduler, which is why batching works the way it does. RxJS and MobX are classic examples of Push-on-Commit. No — pull only checks the relevant dependency chain upward when a value is read. No full-tree traversal required. Not when the result is guaranteed to be consumed immediately (e.g., cursor movement). Lower read latency > cost of extra writes. Most modern signal systems use a hybrid push-pull approach: This combines responsiveness and laziness. Because we often don’t know: Why does fine-grained reactivity need a Push vs. Pull discussion? In coarse-grained systems (like React’s Virtual DOM), diffing the whole tree is abstract enough. But in signal-based systems, one single set() may fan out to hundreds of tiny derivations. Choosing when computation happens affects: Understanding Push vs. Pull gives you the mental model and vocabulary needed to evaluate different reactivity frameworks. In the next article, we’ll explore how different mainstream frameworks design their reactivity systems — and why they made those choices. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse - Push-based systems perform computation immediately when a value changes. - Pull-based systems delay computation until the moment someone reads the value. - Write (ordering): You place your order. - Push (notify on completion): When your meal is ready, your buzzer vibrates or lights up — the update is pushed all the way to you. - Effect (pick up): You walk to the counter to pick it up. - Reactivity interpretation: When a source changes, dependent nodes are recomputed immediately and notified right away. - Write (ordering): You place your drink order. - Mark (state updated only): When the drink is ready, the shop just posts your number on a screen — they don’t notify you directly. - Read → compute (only when needed): When you look up to check the screen, that read operation triggers “oh, it’s ready, I should go pick it up.” - Effect (pick up): You go to the counter. - Reactivity interpretation: Writes only mark nodes as dirty; real computation happens later when someone reads the value. - Push during writes → propagate dirty flags - Pull during reads → compute only when needed - Will this value ever be read? - When will it be read? Pull separates: - “The data changed” (mark dirty) from - “Do I need to act on this?” (compute on read) - Total compute cost (performance) - Interaction latency (UI smoothness) - Scheduling behavior (avoiding jitter & dropped frames)