Skip to content
AgileLogics
5 min read

Actors with Apache Pekko

Prerequisites: Futures and concurrency

The actor model handles concurrency without locks: each actor has private state and processes messages one at a time. Apache Pekko is the open-source (Apache 2.0) continuation of Akka, after Akka changed to a commercial licence in 2022.

// illustrative
import org.apache.pekko.actor.typed.{ActorRef, ActorSystem, Behavior}
import org.apache.pekko.actor.typed.scaladsl.Behaviors

object Counter:
  enum Command:
    case Increment(by: Int)
    case Get(replyTo: ActorRef[Int])

  def apply(count: Int = 0): Behavior[Command] =
    Behaviors.receiveMessage {
      case Command.Increment(by) => Counter(count + by)
      case Command.Get(replyTo)  =>
        replyTo ! count
        Behaviors.same
    }
  • Messages are an enum — the typed API checks at compile time that only valid messages are sent.
  • State changes by returning a new behavior (Counter(count + by)), not by mutating variables.
  • ! ("tell") sends a message without waiting. Because an actor handles one message at a time, its state never needs locking.

Where actors shine

  • Stateful, distributed systems — Pekko Cluster spreads actors across machines; Cluster Sharding keeps one actor per entity (per user, per device).
  • Event sourcing — Pekko Persistence stores events and rebuilds actor state from them.
  • Streaming — Pekko Streams processes unbounded data with back-pressure.
  • Resilience — supervisors restart failed actors ("let it crash"), an idea borrowed from Erlang.

For request/response services without long-lived state, an effect system (Cats Effect, ZIO) is usually simpler.