Private preview Durable Processes for event streams See how it works
Durable execution for streaming applications

Write stateful streaming applications as ordinary Python.

Highwater keeps each key ordered and recovers accepted events, state, and output after failures—with event-time progress built in.

Get early access

One Process per business key. No topology builder. Highwater recovers accepted events and Process state.

balance.py
Running
@process.defn(key="account_id")
@dataclass
class Balance:
    total: int = 0

    @process.event
    async def apply(self, event):
        self.total += event.amount
        return {
            "balance": self.total
        }
Live events State
deposit +$50 $120 $170
purchase −$18 $170 $152
State and output committed together
Ordered per keyDurable state Event-time awareElastic execution

The programming model

Model each key as a Process. Write ordinary Python.

A Process is one durable state machine for every account, device, user, or order. Events for one key stay ordered. Different keys run independently.

Events
BalanceDurable Process
active
S
StatePrivate per key
OutputCommitted atomically
01

Code owns behavior

Use branches, libraries, and models without forcing application logic into a graph of operators.

02

Highwater owns progress

Accepted events, state transitions, timers, and output recover together after execution failures.

03

Keys unlock scale

One key stays consistent while unrelated keys can make progress concurrently.

Event-time progress

Wait for what happened—not when it arrived.

Late events are normal. A Process can wait until configured source progress indicates that no earlier on-time event is expected, then resume ordinary application code.

  • Source progress and idleness are managed for you
  • Late-data policy is explicit and recoverable
  • Timers and event-time gates survive restarts
Order fulfillment live

Created at 10:02, paid at 10:06, and an address update for 10:04 arrived late. Source progress is complete through 10:12, so the event-time gate is open.

10:0010:0510:1010:15
complete through 10:12
await process.wait_until(
  process.event_time >= ship_at
)
gate open

Adaptive batching

Batch by size or latency.

Vectorize model inference under load. When traffic is sparse, Highwater flushes before the oldest event exceeds its latency budget.

Embedding batch96 / 128
Oldest event18ms / 25ms
Dispatch onsizeorlatency

A precise failure contract

Durability is more than remembering a watermark.

Highwater protects the event and every state transition it causes.

Durable admission

An event is accepted only after its identity and payload are durably recorded.

Ordered state

One key commits one transition at a time, even when an invocation is retried.

Atomic output

Process state and Highwater output become visible in the same commit.

Recoverable progress

Mailboxes, timers, event-time progress, and operator state recover together.

Application code may run more than once after failure. Fenced completions prevent stale attempts from committing; external APIs should use a stable idempotency key.

Built for application logic

Streams with decisions inside.

Use native streaming state where it helps. Keep the logic that makes your product different in code.

01

Online recommendations

Join live behavior with the version of product data valid when the event occurred.

Temporal joins
02

Device intelligence

Track per-device state, close event-time windows, and respond to meaningful conditions.

Event-time gates
03

Risk and account state

Apply authorizations, reversals, and policy changes in consistent per-account order.

Keyed Processes
04

Model inference

Batch embeddings or predictions by size and latency without turning off the stream.

Adaptive batches

Early access

Build streaming applications without operating a stream-processing stack.

Join the early-access list for product updates, design partnerships, and the first hosted deployments.