Background
Why the reactor model exists, what it offers, and the principles that make it work.
The problem
Software that drives physical systems — robots, vehicles, factory equipment, medical devices — must coordinate many activities in parallel and in real time. Data from many sensors flows across multiple processors and networked subsystems and must be turned into timely actions on the physical world. As system complexity rises, concurrency and timing become a dominant engineering challenge.
Existing tools struggle to meet each challenge in isolation and break down entirely on their combination. Hard real-time deadlines can be met on a single thread with a static schedule, but only with code whose worst-case execution time can be bounded. Synchronous-reactive languages — Esterel, Lustre, SCADE — establish deterministic semantics within a synchronous, single-threaded execution model and have been used in safety-critical industrial systems for decades, but they do not address parallel execution across cores or distributed deployment. Concurrency at scale can be achieved at low levels with threads, at higher levels with message-passing actors, or at architectural scale with service-oriented systems — but often at the cost of nondeterminism.
Conventional timing and concurrency models do not compose; their limitations compound. Once parallel activities share a processor or a network, timing and behavioral guarantees that hold in isolation no longer hold in concert. A task that should run every ten milliseconds may slip; an event that should be handled before another may be handled after. Two runs of the same code on the same inputs can produce different results, in different orders, at different moments. Where a missed deadline can damage equipment or endanger people, such nondeterminism is more than an inconvenience: it makes systems hard to test, hard to debug, and hard to verify.
How reactors meet the challenge
The reactor model addresses both concurrency and timing within a single discipline. Programs are built from reactors: components that communicate explicitly through ports. Events flowing through those ports carry tags that fix their order and simultaneity, independent of physical timing. The result is software whose behavior is reproducible by construction: the same inputs, arriving at the same external times, always produce the same results, whether the program runs on one core, many cores, or a distributed network of nodes.
Causal reactivity
Reactors do not share memory and do not call each other directly; they communicate only by sending values through their output ports, which are wired to the inputs of other reactors. Reactors respond to inputs and produce outputs via reactions. Reaction order is determined by dependencies implied by the port connections among the reactors that contain them.
Logical time
Every event carries a tag that represents the event's place in the program's causal order, not just the wall-clock time at which it was produced. A runtime schedules reactions according to clear rules over these tags: events with earlier tags are processed before later ones, and reactions that share a tag follow declared dependencies. The wall clock still matters when the program interacts with the physical world, but it never decides the order in which the program's own logic runs. Given the same inputs and the same external timing, the same program produces the same result every time.
Composition
Reactors compose. A reactor can contain other reactors, with their ports wired together, forming a hierarchy that mirrors the structure of the system being built. Modules built independently can be combined without re-engineering their internals, because the rules of the model — events, ports, time tags — apply uniformly at every level.
Why the model matters
The guarantees of the model shift the responsibility for managing concurrency and timing from the engineer to the runtime, making reactor programs reproducible by construction and easier to understand, test, and verify.
The model also makes the relationship between logical time (when things are intended to happen) and physical time (when things actually happen) part of application logic rather than a property only of the underlying system. This has enabled quantitative reasoning about availability and consistency at the application level, producing the CAL theorem (Lee, Bateni, Lin, Lohstroh, Menard, Quantifying and Generalizing the CAP Theorem, 2021): a generalization of Brewer's CAP theorem that replaces the binary notion of network partition with a numerical measure of latency, yielding an algebraic relation among consistency, availability, and latency. The implications of these trade-offs, and how applications can most effectively leverage them, are an active area of current research.
The model's operational semantics also admit a machine-checked proof of determinism (Rossel, Lin, Lohstroh, Castrillon, Goens, Provable Determinism for Software in Cyber-Physical Systems, VSTTE 2023); the accompanying Lean 4 proof development is at lf-lang/reactor-model.
Origins
The reactor model was first defined in the paper of Lohstroh et al. that introduced it, and expanded on in Lohstroh's PhD dissertation, advised by Prof. Edward A. Lee:
- Marten Lohstroh, Iñigo Incer Romero, Andrés Goens, Patricia Derler, Jeronimo Castrillon, Edward A. Lee, and Alberto Sangiovanni-Vincentelli. Reactors: A Deterministic Model for Composable Reactive Systems. CyPhy'19, held in conjunction with ESWEEK 2019.
- Marten Lohstroh. Reactors: A Deterministic Model of Concurrent Computation for Reactive Systems. PhD dissertation, UC Berkeley, UCB/EECS-2020-235, 2020.
The reactor model continues a lineage of time-centric models of computation developed in Edward A. Lee's Ptolemy project at UC Berkeley. It draws on synchronous-reactive languages, discrete-event modeling, dataflow, and the actor model — combining and refining ideas from each into a programming model with deterministic concurrency under explicit logical time.
Alongside the formal model, Lohstroh's dissertation presented Lingua Franca, its first concrete implementation: a polyglot coordination language in which reactor structure is described in LF while the code inside reactions is written in a chosen target language (C, C++, Python, Rust, or TypeScript), with a toolchain that combines the two into an executable program. Lingua Franca has been developed through an international collaboration spanning UC Berkeley, TU Dresden, Kiel University, NTNU, UT Dallas, the University of Arizona, and other partner institutions. Most subsequent research applying the reactor model to real systems has been carried out in the Lingua Franca ecosystem; see lf-lang.org/research for that body of work.