If you have ever spent a late night chasing a deadlock in a Java service. Or watched a microservice cluster collapse because a single thread pool filled up, you already understand the core pain that the actor model solves. What you might not know is that the Czech word herec means "actor" - and in distributed systems engineering, the actor model isn't about theater. It is a formal, mathematically grounded approach to concurrency that treats isolated computational units as the fundamental building block of software. In production environments, we found that adopting this model-often called simply herec by our Prague-based team-eliminated entire classes of race condition bugs that had plagued our stateful services for months.
The actor model was first described by Carl Hewitt, Peter Bishop,, and and Richard Steiger in 1973Their paper, A Universal Modular Actor Formalism for Artificial Intelligence, proposed that computation could be understood as a collection of independent entities that communicate only by passing messages. No shared memory - no locks, no semaphores. Each herec owns its private state and decides how to handle the next message. That simple idea-now fifty years old-has powered some of the most resilient systems ever built.
The actor model isn't just a concurrency abstraction-it is a complete rethink of how we structure state, failure. And communication in distributed systems. In this article, I will walk through the technical foundations, real-world implementations, testing strategies. And trade-offs of building with herec-style actors. Along the way, I will share concrete lessons from production deployments and cite the exact frameworks and documentation we used.
The Linguistic Origins and Technical Meaning of herec
In Czech and Slovak, herec translates directly to "actor" in English. That linguistic fact is more than trivia for a multinational engineering team. When we first introduced the actor model to our Bratislava and Prague offices, the term herec became a natural shorthand in code reviews and design docs. Saying "this herec handles payment state" was clearer than saying "this actor instance" because it removed ambiguity with the JVM's java lang. Thread or Kubernetes' Actor resources. The word also reminded us that the model has a long intellectual history, originating long before microservices became a buzzword.
Technically, an herec is a computational entity that encapsulates state, behavior. And a mailbox. Unlike an object in OOP, which shares memory with other objects through references, an herec can only be influenced by sending it a message. That message is an immutable, serializable value placed in the recipient's mailbox. The recipient processes messages one at a time, in the order they're received. And may change its internal state or spawn new herec instances as a result. This eliminates the need for explicit locking because no two herec instances ever touch the same memory location simultaneously.
The formal definition from Hewitt's 1973 paper includes three primitive operations: send, create, become. Send delivers a message to a known address. Create instantiates a new actor with a given behavior. Become replaces the current behavior with a new one for handling subsequent messages. These three operations are sufficient to express any concurrent computation. In practice, modern actor frameworks add supervision - location transparency, and persistence. But the core remains unchanged.
Why Shared-State Concurrency Fails Under Realistic Distributed Conditions
When a service runs on a single machine, shared mutable state with locks seems manageable. A synchronized block in Java or a Mutex in Go can protect a critical section. Problems begin when that service must scale horizontally. Multiple replicas mean locks don't work across processes unless you add a distributed lock manager. Which brings its own failure modes: split-brain - lease expiry. And latency. Our team once ran a payment orchestrator that used Redis-based distributed locks. Under a network partition between two availability zones, both replicas acquired the lock on their local Redis nodes and double-processed a batch. That was the moment we started exploring herec-based designs.
The deeper issue is that shared-state concurrency couples identity, state, execution. A thread holds a reference to an object, mutates its fields. And assumes no other thread is doing the same. That assumption breaks the moment you introduce async callbacks or distributed calls. The actor model decouples these concerns: an herec has a stable identity (its address), it owns its state exclusively. And execution happens only when it processes a message from its mailbox. No other thread or process can reach into that state, and the mailbox becomes a natural synchronization boundary
In production environments, we found that moving from a thread-per-request model with shared repositories to an herec-per-aggregate model reduced our deadlock incidents from roughly one per week to zero over a six-month period. That wasn't because our engineers became better at writing locks. It was because the architecture made the unsafe pattern impossible to express. You simply can't have a race condition if there's no shared mutable state to race on.
Core Primitives: Messages, Mailboxes, and Behavior Switching in herec
Every herec system is built on three primitives: messages, mailboxes. And behavior switching. A message is an immutable data structure, typically a plain object or a tagged union, that carries intent and parameters. For example, a Checkout actor might receive messages like AddItem(productId, quantity), ApplyCoupon(code), PlaceOrder(customerId). The actor's mailbox is a FIFO queue that stores incoming
Need a Custom App Built?
Let's discuss your project and bring your ideas to life.
Contact Me Today โ