Back to Blog
Marcus Ogundimu

How LaserData Handles Concurrent Agent Sessions

Run 50 agents against one session store and realistic load testing will expose write contention within minutes. Nothing is necessarily wrong with the agents: they read shared configuration, write per-agent context, and sometimes update shared records that several agents need. Mutable data shared by concurrent processes will contend. The design task is to keep that contention from becoming either a performance bottleneck or a correctness failure.

This post covers LaserData's isolation model, the choices that preserve low read latency under high concurrency, and the intentional limits to understand before depending on it.

Concurrency creates two problems

Concurrent sessions using one data store create two separate problems, each requiring its own solution.

The first is performance. Write contention creates lock waits, raising tail latency for every session, including those not directly conflicting. With pessimistic locking, session A locks a row to update shared state, while session B waits for that lock to be released. At high concurrency, blocked writers form a queue that appears as p99 spikes even when the median remains fast.

The second is correctness. Without isolation, an agent may read another agent's intermediate transaction state. If it consumes context from a sibling session that later rolls back, its behavior can diverge. Reproducing or debugging that behavior is difficult because it depends on exact interleaving timing.

Relational databases address both concerns with transaction isolation levels. For an agent-specific data layer, the questions are which level matches agent access patterns and whether a general-purpose transaction model is the right primitive.

Session-scoped and shared state

Our first design choice was to separate session-scoped state from shared state logically, giving each category different isolation semantics.

Session-scoped state belongs to one agent session: its current context window, task working memory, and intermediate outputs. During normal operation, no other session reads or writes it. Isolation is therefore simple: writes appear immediately within the session and remain invisible elsewhere. With no sharing, there is no contention.

Shared state is data that several sessions may read or write, such as a common knowledge base, behavior-controlling configuration records, or accumulated results from agents on a coordinated task. This is the part that needs deliberate isolation design.

LaserData represents these categories separately, so expensive isolation is not applied to most access, which is session-scoped. Shared-state updates still receive correct semantics. Most agent operations touch private session data; shared-state access is the exception.

Snapshot isolation for shared reads

LaserData uses snapshot isolation for shared-state reads. When a session starts reading, it receives a consistent snapshot from the beginning of that read operation. Writes from other sessions do not change the view, so the session sees stable shared state throughout its read operations while concurrent writes continue.

This protects a specific agent behavior. Suppose an agent reads three related shared records before deciding from their combined values. Without a snapshot, it could read A, then another session could update B and C, and the agent could read those afterward. The resulting mixed state never existed as a coherent whole. Snapshot isolation returns A, B, and C as they existed at one snapshot point, guaranteeing a consistent combined view.

Snapshot isolation does not stop two sessions from submitting conflicting writes. It stops readers from observing inconsistent partial state. Conflicting writes need a separate mechanism.

Optimistic concurrency for shared writes

LaserData uses optimistic concurrency, not pessimistic locking, for shared-state writes. Each record has a version number. A session that reads a record intending to update it records the current version, then includes that version in its write. The write succeeds only if the record still has the same version. If another session updated it, the version has advanced, the write returns a conflict error, and the session must retry.

With low contention, which is the common case, writes complete without lock-acquisition overhead. Optimistic concurrency costs more only when a conflict occurs. When several sessions truly update one shared record simultaneously, retries cost time, but that cost is limited to conflicting writes rather than every write.

The tradeoff is that the application must handle write conflicts. Agent code needs to catch the failed write, decide how to retry, reread the updated record, reconsider the decision that produced the write, and attempt the update again. That behavior must be designed explicitly instead of delegated to a transaction retry loop.

Optimizing reads under concurrency

Snapshot isolation enables an important read-path property at scale: writes never block reads.

In a pessimistic locking system, a read arriving during a long write transaction may wait for commit before returning consistent data. With snapshot isolation, it reads immediately from its snapshot. The concurrent write does not add time to that read.

In LaserData, p50 read latency under concurrent writes therefore stays close to p50 latency with no concurrent writes. Writes create new snapshot versions while existing reads continue against the prior snapshot. Read-heavy agent workloads, the common case, retain stable latency even with substantial background write activity.

Multiplexing sessions over one connection

Connection-level parallelism raises a separate issue. An agent runtime with 50 sessions may not want 50 TCP connections to the data backend. Setup overhead and per-connection resources make that impractical at high session counts.

LaserData sends multiple logical sessions over one physical connection, attaching a session identifier to every request. The server uses that context to select visible session-scoped state and the applicable isolation scope. On the client, agent threads can share one connection object while each supplies its own session identifier.

This choice targets agent workloads. Agents in one deployment often perform similar operations against similar data. Logical-session pooling keeps physical connection count proportional to distinct threads rather than distinct sessions, which can differ by an order of magnitude in practice.

What this model does not solve

The limits are deliberate. Snapshot isolation keeps readers from seeing partial writes, but it does not prevent write skew. This occurs when two sessions read overlapping shared data, make decisions from those reads, and then perform updates that are each valid alone but inconsistent together.

For example, two agents can read a shared counter they conditionally intend to increment. Both see a value that passes the condition and write an increment. Because neither directly conflicts on the same record, both writes succeed, yet the combined result violates the invariant that the counter increments only once. Preventing this requires serializable isolation, which costs more to implement and run than snapshot isolation.

We are not saying snapshot isolation provides the strongest possible consistency. We are saying it matches the access patterns we observed in the agent use cases we care about. Most workloads use largely independent data, so write skew is usually not practical. If strict serializability is required, such as for a coordinator managing a budget claimed by multiple sub-agents, add application-level locking over LaserData's optimistic primitives or avoid shared mutable counters in the data model.

LaserData

Build your agent on the right data layer.

Store, stream, and query agent context at speed. Free tier, no credit card required.

Get API Key