Agent runtimes | Published October 29, 2026

Infinity makes waiting agents cheap. The resume contract makes them safe.

Hydro Infinity treats a tool call like an asynchronous suspension point: commit the conversation, dispatch the work, release the process, then resume from a message. That is a compelling execution model. It is not a reliability guarantee until ordering, replay, side effects, and event provenance are tested as one protocol.

Apache-2.0 research releaseBounded execution slicesAt-least-once replaySources checked Oct 29
Event-driven agent runtime with queues, durable history, tools, and resume receipts

The useful idea is not “75,000 agents.” It is history as a continuation.

AWS and UC Berkeley's Hydro project released Infinity under Apache-2.0 on October 23, 2026. The headline benchmark says roughly 75,000 idle agents can fit within 8 GB. The architecture matters more: a waiting agent owns no task, stack, connection, or process. Its continuation is persisted conversation history plus runtime state, and the next message reconstructs the work.

Most simple agent harnesses are blocking loops. They call a model, receive a tool request, invoke the tool, wait, append the result, and call the model again. If a build takes twenty minutes, an approval takes a day, or a child agent reports hours later, the process remains occupied or the application invents a second orchestration layer. Either way, waiting becomes a resource and recovery problem.

Infinity cuts the loop into bounded execution slices. One slice loads a thread, consumes one input message, asks the model for one completion, commits a completed turn, dispatches at most one tool call, and exits. Tool results, timer wakeups, user messages, OAuth challenges, subscription events, and child reports all return through an input queue. The runtime can disappear between slices.

A suspended agent is cheap only because every fact needed to resume it has moved from process memory into a durable protocol.

This is the same conceptual move that stackless coroutines made for asynchronous programs: do not reserve an operating-system thread for time spent waiting. But agent continuations have unusual risks. Their state includes model-visible history, tool-call identity, permissions, human approvals, compaction boundaries, external side effects, and untrusted event payloads. A runtime can resume the bytes correctly and still resume the wrong authority, duplicate an effect, inject a forged result, or continue from a state the operator believed was stopped.

The adoption question is therefore not “does hibernation work?” It is “can this exact runtime prove that every resume belongs to the intended thread, follows the committed turn, preserves the correct authority, handles redelivery, and leaves an auditable effect record?”

One invariant shapes the entire runtime

Infinity's documentation states a simple invariant: an execution slice never blocks on anything external. A slice may read and write its stores, call the model, and enqueue work, but it does not wait for a tool, timer, another agent, or user. That invariant makes a local resident process and an AWS Lambda deployment share the same agent logic.

ConcernBlocking harnessContinuation runtime
Tool latencyProcess waits or custom job layer takes overTurn commits, tool dispatches, slice exits
Idle memoryTask, connection, and in-memory state may remainConversation and state live in stores
Resume triggerReturn value inside the same call stackMessage on a thread input queue
ConcurrencyUsually process or task per active loopSerialize inside a thread, parallelize across threads
Delivery semanticsOften implicitAt-least-once queue plus stable message IDs
Correctness boundaryCall stack and local stateCommit, queue, store, dispatch, replay, and provenance

Each input carries a thread identifier and stable message ID. Within one thread, slices must be serialized because two concurrent slices could read the same history and overwrite each other's turns. Across different threads, work can proceed concurrently. The AWS reference uses SQS FIFO message groups to serialize per thread while Lambda scales message groups independently.

Streaming model output is buffered until the turn completes. A failed partial stream is discarded rather than published as history. When a completion ends in a tool call, the runtime persists the turn before dispatching that tool. That ordering prevents a fast tool result from arriving before the history contains the call it answers.

Queues redeliver. Infinity records processed IDs in a state store so a duplicate input can be skipped. This makes the slice idempotent relative to message processing. It does not automatically make the external tool effect idempotent. If a payment, email, deployment, or ticket update succeeded but the acknowledgement was lost, replaying the tool may still duplicate the consequence.

Write the resume contract before choosing infrastructure

A team evaluating Infinity should define the contract independently of SQS, Lambda, Aurora DSQL, DynamoDB, or the local in-memory implementation. Infrastructure can implement an invariant; it should not be the only place the invariant is described.

resume_contract: v1
thread:
  identity: immutable_thread_id
  ordering: fifo_per_thread
input:
  message_id: stable_and_unique
  provenance: signed_origin_and_request_binding
turn:
  commit: complete_buffer_before_dispatch
  partial_stream: discard_and_retry
tool_effect:
  request_id: stable_idempotency_key
  authority: capability_snapshot
  receipt: required
replay:
  duplicate_input: skip
  uncertain_effect: reconcile_before_retry
event:
  bind_to: original_request_id
  expiry: required
  untrusted_payload: schema_and_policy_check
operator:
  stop: durable_tombstone
  park_after: bounded_attempts
  resume_receipt: required

The contract distinguishes message processing from effect processing. A durable record needs the input ID, thread version, history hash before and after the slice, model and prompt configuration, tool request ID, capability snapshot, dispatch status, effect receipt, result ID, retry count, and operator decision. When an external system cannot accept an idempotency key, the runtime needs a reconciliation query before retry.

{
  "resume_id": "res-0192",
  "thread_id": "thr-44",
  "input_id": "msg-8841",
  "history_before": "sha256:before",
  "history_after": "sha256:after",
  "input_disposition": "first_delivery",
  "tool_request_id": "tool-728",
  "authority_snapshot": "cap-v7",
  "turn_commit": "complete",
  "dispatch": "accepted",
  "effect_state": "pending",
  "retry_count": 0,
  "event_provenance": "verified",
  "runtime_build": "infinity@commit"
}

A resume receipt should be generated outside model prose. The model may explain why it requested a tool, but the runtime must attest what it loaded, committed, dispatched, skipped, or reconciled. Store sensitive payloads by controlled reference or digest when the reviewer does not need the full content.

Durable-before-dispatch is the critical ordering rule

input queue        runtime slice       history store       tool broker
    |                    |                   |                  |
    |-- message M ------>|                   |                  |
    |                    |-- load thread --->|                  |
    |                    |<-- history v12 ---|                  |
    |                    |-- model turn ----------------------- |
    |                    |-- commit call --->|                  |
    |                    |<-- history v13 ---|                  |
    |                    |-- dispatch T ----------------------->|
    |                    |-- slice exits                        |
    |                    |                   |   effect + receipt
    |<-- result(T,id) ------------------------------------------|
    |-- result message ->|   next slice resumes                 |

The dangerous alternative dispatches first and commits later. A fast result can then be delivered to a thread whose history does not contain the corresponding request. A crash between the two operations creates an orphan result or an effect without a durable cause. Commit-first does not solve every dual-write problem, but it establishes an auditable causal order.

A practical slice driver should make state transitions explicit:

async fn run_slice(input: InputMessage) -> Result<Receipt> {
    let mut thread = store.load(input.thread_id).await?;
    if state.seen(input.thread_id, input.message_id).await? {
        return Ok(receipt("duplicate_skipped"));
    }
    let turn = model.complete(thread.history(), input.payload).await?;
    let committed = store.commit_complete_turn(thread.version, turn).await?;
    state.mark_seen(input.message_id, committed.version).await?;
    if let Some(call) = committed.tool_call() {
        broker.dispatch(call.with_idempotency_key()).await?;
    }
    Ok(receipt("committed_before_dispatch"))
}

Real code must handle atomicity across the conversation store and deduplication state. If those records live in separate systems, test every crash boundary. A message marked seen before the turn commits can disappear. A turn committed before the message is marked seen can be appended twice. An outbox pattern, transactional store, or carefully reconciled state machine is safer than relying on happy-path ordering.

Synthetic events preserve API shape, not event truth

Infinity uses synthetic tool calls to present asynchronous events to models that expect synchronous tool-call traces. A subscription can return its first result and later send more events. A child thread can report progress and a final result to its parent using the same message path. This is elegant because the runtime does not need a second model-facing event language.

It also creates a security boundary. The model sees an event as structured conversation content. The runtime must establish who emitted it, which original request it belongs to, whether the producer still has authority, whether the event is fresh, and whether the payload matches the declared schema. A string that names a tool call is not proof of origin.

Use signed or authenticated producer identity, request binding, monotonically checked sequence information where required, expiry, payload size limits, schema validation, policy evaluation, and a recorded routing decision. Internet-derived event content must remain untrusted even when its envelope is authentic. Never allow the model to manufacture the reserved injected-event tool name.

Threaded event handling can protect the subscribing thread's context by delegating work to temporary child threads. Associative inline events can be appropriate for log lines or progress updates that belong in the same history. Treat that choice as an acceptance decision: test context growth, ordering, cancellation, late events, conflicting child results, compaction, and the operator's ability to reconstruct who knew what when.

Read the benchmark at the layer it measures

The AWS post reports a benchmark that launched waves of 80,000 agents, ran twenty turns per agent, and processed 3.2 million simulated completions on one AMD EPYC thread with in-memory stores. Resident memory grew by roughly 100 KB per idle agent, leading to the estimate that about 75,000 agents fit within 8 GB.

That is useful evidence for the runtime's resident-memory shape. It does not include the cost and capacity of real model inference, production database latency, tool services, network calls, payload growth, long histories, encryption, telemetry, tenant isolation, human approvals, or failure recovery. It is also first-party evidence and has not been treated here as an independent benchmark.

ClaimEvidence supportsStill requires proof
Idle agents are lightweightNo task, stack, or connection per suspended agentYour history sizes, indexes, encryption, and stores
Many threads can share a processSynthetic resident-memory benchmarkModel and tool throughput under real workloads
Serverless waiting can scale to zeroEach slice exits after bounded workQueue, database, scheduler, and cold-start economics
Per-thread ordering is preservedFIFO group design and runtime contractCrash, redelivery, migration, and operator-stop tests
Events fit model APIsSynthetic tool-call representationModel behavior under interleaving and hostile payloads

The public issue tracker is part of the design evidence

Infinity is explicitly an early research release. Current public issues include simultaneous approval prompts, sandbox state that becomes unusable after resume, racing child finalization, misleading compaction behavior, empty summaries, stop operations that do not stop, silent retry loops, and reboot persistence problems. Issue titles do not prove every bug affects the latest commit, but they identify the acceptance tests a serious pilot should run.

FailureConsequenceAcceptance test
Duplicate inputRepeated model turn or effectRedeliver before and after commit; verify one outcome
Child finalization raceConflicted or resurrected stateComplete, cancel, and merge children concurrently
Approval prompt collisionHuman approves the wrong actionTrigger multiple choices and bind each to request identity
Sandbox resume driftThread wakes with invalid workspace authoritySuspend, rotate, clone, and resume across sandbox states
Compaction discontinuityLost instructions or orphan child contextCompact before and after spawn, then reconstruct lineage
Ineffective stopOperator believes work ended while effects continuePersist stop tombstone and reject every later event
Unbounded retryCost loop and repeated side effectsForce stream stalls and park after a declared budget
Forged eventModel acts on unauthenticated payloadInject wrong producer, request, sequence, and expired event

A 30-day consequence-based pilot

  1. Pin one Infinity commit, model configuration, tool schema, store implementation, queue configuration, and deployment template.
  2. Choose read-only or reversible workloads with long waits: CI observation, repository triage, scheduled research, or human approval.
  3. Define the resume contract and receipt schema before running a happy path.
  4. Record baseline memory, queue latency, store latency, slice duration, history growth, model calls, tool time, and cost.
  5. Inject duplicate, delayed, reordered, expired, oversized, malformed, and forged messages.
  6. Crash before commit, after commit, before dispatch, after effect, before acknowledgement, and during result persistence.
  7. Test multiple simultaneous approvals, child reports, cancellation, compaction, sandbox suspension, and operator stop.
  8. Require idempotency or reconciliation for every external effect. Do not rely on slice deduplication alone.
  9. Run tenant and capability tests so a resumed thread cannot inherit another thread's store, tool, credential, or event.
  10. Expand only if recovery receipts are complete, no duplicate consequence escapes, and rollback works from a clean deployment.

Useful metrics include duplicate inputs suppressed, uncertain effects reconciled, late events rejected, mean and maximum resume latency, history bytes per thread, compaction failures, parked retries, operator-stop violations, approval misbindings, store conflicts, and recovery time. “Agents resident” is not enough. The runtime exists to preserve correct work across waiting, failure, and movement.

Adoption rule: treat Infinity as an instructive runtime architecture and early implementation. Put irreversible tools behind an independent effect broker until your own replay, provenance, and recovery evidence supports more authority.

Frequently asked questions

Is Infinity a model or an agent framework?

It is a Rust agent runtime and tool protocol in the Hydro project. It can host model-driven threads, tools, subscriptions, child agents, local processes, and serverless deployments. It does not replace the model, application policy, or external effect controls.

Does it guarantee exactly-once processing?

Stable IDs and deduplication support idempotent slice processing on an at-least-once queue. External tools still need idempotency keys, durable receipts, and reconciliation because an effect and its acknowledgement can fail independently.

Is it production ready?

The release is described as early research. The public implementation and docs are substantial enough for a bounded pilot, while the issue tracker and open research questions argue against treating the architecture as a production certificate.

How is this different from a durable workflow engine?

Both suspend work and resume from durable state. Infinity is specialized for model conversations, tool calls, subscriptions, synthetic model-facing events, and agent trees. Mature workflow engines may offer stronger operational history, timers, retries, and activity semantics. Evaluate integration rather than assuming replacement.

Sources and further reading

Sources were accessed October 29, 2026. GitHub counts are point-in-time signals, and the benchmark is identified as first-party synthetic evidence.