Browse Learn Clojure Foundations as a Java Developer

Create Agents and Send Actions

Create Clojure agents for one independent asynchronous state value, send action functions with send or send-off, and keep each action focused on producing the next state.

An agent holds one state value and processes action functions asynchronously. Each action receives the current state and returns the next state.

The important difference from an atom is timing. swap! updates an atom before returning. send queues an agent action and returns before the action necessarily runs.

Agent Basics

Operation Meaning Java comparison
agent Create an agent with an initial state. Stateful worker initialization.
send Queue a CPU-oriented action. Submit short CPU work.
send-off Queue a potentially blocking action. Submit blocking work.
@agent Read the latest completed state. Snapshot read.
await Wait for already-dispatched actions to finish. Join submitted work.

Agents process actions for a single agent one at a time. Different agents can make progress independently.

A Focused Example

 1(def audit-events (agent []))
 2
 3(defn add-event [events event]
 4  (conj events event))
 5
 6(defn record-event! [event]
 7  (send audit-events
 8        add-event
 9        event))
10
11(record-event! {:type :user-created
12                :id "u-100"})

The action function add-event is ordinary pure logic. The agent supplies serialized asynchronous state ownership.

Choosing Agent Dispatch

Dispatch Use when Avoid when
send The action is CPU-bound and short. The action blocks on I/O.
send-off The action may block on files, network, or waiting. The action should stay on bounded CPU resources.

Do not use agents merely to hide arbitrary slow work. If the work has no state value, a future, executor, core.async pipeline, or job queue may be clearer.

What Agents Are Not

Misread Better model
“Agent means actor system.” An agent serializes functions around one state value.
“Agent means task queue.” Use a queue when tasks, retries, and backpressure are the main concern.
“Agent means durable background processing.” Use durable storage or a broker when restart safety matters.
“Agent means shared mutable object.” Store immutable data and return the next value.

Knowledge Check

### What does an agent action function return? - [x] The agent's next state value. - [ ] A Java thread object. - [ ] A database transaction. - [ ] A lock release token. > **Explanation:** Agent actions transform the current state into the next state. The agent owns when that transition is applied. ### When is `send-off` a better fit than `send`? - [x] When the action may block on I/O. - [ ] When the action must update synchronously. - [ ] When several refs must commit together. - [ ] When the value is read with `@`. > **Explanation:** `send` is for CPU-oriented actions; `send-off` is intended for actions that may block. ### What is the strongest reason to choose an agent? - [x] One independent state value needs serialized asynchronous updates. - [ ] Every task in the program needs a thread. - [ ] A durable job queue is required. - [ ] Several identities must commit atomically. > **Explanation:** Agents are about asynchronous state ownership for one value. Other coordination problems need other tools.
Revised on Saturday, May 23, 2026