Skip to content

Pulse/Durable, Eino and Temporal: one comparison set ​

This page is the single current performance comparison for Pulse (with Durable for reliable execution), Eino and Temporal across execution, observation, resources, storage and recovery. The 2026-10-17 in-memory comparison remains unchanged; formal SQLite, Temporal native-persistence and process-recovery data are updated to the 2026-10-23 official-module rerun.

The two collections have different scopes. The new data is not presented as a full multidimensional rerun, and no unmeasured Go 1.26-versus-1.25 speedup is claimed.

Versions, samples and guarantees ​

The formal SQLite rerun targets the Pulse v0.5.1 release candidate. Core runtime source is unchanged from the v0.5.0 formal release; Go 1.26 is the unified toolchain. Durable and official sqlitestore use the formal v0.1.0 tag. No local replace.

ComponentPinned identity
Pulse Core source baselinev0.5.0 formal release / v0.5.1 release candidate
Durable / official sqlitestorev0.1.0 / v0.1.0
Einov0.9.21
Temporal SDK / CLI / Serverv1.50.0 / 1.9.1 / 1.32.0
SQLite drivermodernc.org/sqlite v1.60.1
Formal SQLite benchmark hostGo 1.26.0 / windows/amd64

Windows 11 / i9-14900HX; GOMAXPROCS=4 per Go process, including Server, and business concurrency=4. This is not a four-core affinity limit shared across processes. chain/wide/diamonds, N=1/10/100/1000/10000, rounds=1/256. One node is one real task/regular Activity with actual direct-predecessor values. Per-node values, counts, concurrency and reuse are checked before freezing a non-race binary and rotating cases serially.

The table above is the historical 2026-10-17 full-dimensional matrix and remains only to explain the retained in-memory execution, observation and resource data. The current formal SQLite rerun has these valid records:

Formal SQLite rerun matrixPlanned identitiesStatus
checkpoint / Pulse4536 ok, 3 deadline, 6 not_repeated
checkpoint / Eino4515 not_equivalent, 30 not_repeated
Temporal native4530 ok, 1 deadline, 4 hard_timeout, 10 not_repeated
recovery3636 ok

The formal rerun has 171 valid records and retains another 45 Temporal checkpoint configuration diagnostics; its overall status is COMPLETED_WITH_ERRORS. — means no completed cost, never zero; timeouts and not_repeated points are neither zero-filled nor extrapolated. The historical 1062 planned identities are not combined with the formal SQLite numbers.

DimensionPulse / DurableEinoTemporal
Native executionIn-memory Pulse, fresh Execution per runcompose Graph, AllPredecessor, unique output keysReal Server/worker, always native persistence
ObservationObserver lifecycle countersGraph/Lambda start/end/error callbacksNon-replay Workflow/Activity interceptors
Reliable confirmationDurable Store confirmation before publicationNo automatic per-node save on normal success; active CheckPointStore interrupt separatelyNative history and Activity completion confirmation
RecoveryKill host after confirmed prefix; new-process ResumeExit after active checkpoint; new-process resumeConfirmed prefix without in-flight Activity, worker kill; Server restart separately

Eino's host semaphore limits business bodies. Its host cancels and joins those bodies after errors, without promising all engine goroutines have exited. Temporal sets MaximumAttempts=1 and acquires the workflow semaphore after dependencies, before scheduling Activities.

Native execution and preparation ​

The following rounds=1 numbers are ms, medians of five repeated reuse-batch means. Windows uses QPC to resolve short intervals. CSV retains min–max, both workloads, first runs and setup. These are not online p50s or confidence intervals.

shape / NPulse (ms)Eino (ms)Temporal (ms)
chain / 10.00433750.0065289253.826
chain / 1000.2621070.6136915049.45
chain / 10002.8153538.6123—
chain / 1000031.29354867—
wide / 10.00433770.0062323229.887
wide / 1000.1708950.7141131374.74
wide / 10001.8701239.940311183.6
wide / 1000019.24154824.91—
diamonds / 10.004060.0064852225.973
diamonds / 1000.2825390.8346923400.07
diamonds / 10002.8787340.5372—
diamonds / 1000034.2144796.76—

Native reuse cost

Temporal chain/diamonds N=1000 and every N=10000 configuration did not finish the whole case; no runtime is extrapolated and no wrong-result claim follows. Wide N=1000 completed. All Pulse/Eino native plain/observe plans completed. This tiny-task difference is not a proportional speedup for complete Agent applications. No profiles were collected this round, so curve changes are not attributed to proven internal hotspots.

N=100 chain / stagePulse (ms)Eino (ms)Temporal (ms)
server_setup_ns00364.083
adapter_setup_ns0.06480.491966.1348
first_ns0.49391.0354186.82
run_ns0.2621070.6136915049.45

Stage responsibilities differ: Pulse builds a graph and validates on first start; Eino assembles/compiles; Temporal adapter setup connects/registers/starts a worker, with Server preparation separate. First execution covers submission through correct-result confirmation; reuse is subsequent. Do not subtract stage medians for attribution. Temporal persistence is retained rather than presented as an equivalent in-memory guarantee.

Observation ​

N=100 / shapePulse plain → observe (ms)Eino plain → observe (ms)Temporal plain → observe (ms)
chain0.262107 → 0.2710020.613691 → 0.6629095049.45 → 5052.55
wide0.170895 → 0.1733960.714113 → 0.7417531374.74 → 1301.09
diamonds0.282539 → 0.2838720.834692 → 0.8819223400.07 → 3398.72

Plain and observe costs

All use public extension hooks with atomic counters and no external logging. Coverage and event counts differ; differences are not prices for identical features. Some observe medians are lower: these are independently sampled variations, not evidence that observation accelerates execution. CSV retains event types/counts and ranges.

Equal-work CPU and memory ​

A separate resource experiment performs one first run plus one reuse for every framework, including process startup, preparation and GC. Temporal's independent Server belongs to the Windows Job. The table uses chain/rounds=1; CPU is seconds and RSS is MiB.

chain / NPulse CPU s / RSS MiBEino CPU s / RSS MiBTemporal CPU s / RSS MiB
10.015625 / 18.35940.015625 / 17.7930.609375 / 170.289
1000.015625 / 18.39060.03125 / 17.79692.53125 / 213.496
10000.015625 / 18.41020.140625 / 26.9883— / —

Equal-work CPU and sampled RSS

Job CPU includes exited descendants. Local process CPU accounting is quantized at roughly 15.625ms; equal small values do not prove identical CPU work. RSS is the largest simultaneous tree sum observed every 25ms and may miss a short peak. The common binary links all adapters: this includes a common harness baseline, not minimal standalone deployment footprints. Incomplete-case resources remain in raw data rather than completed-cost statistics.

CSV also retains cumulative process-local Go reuse allocations. Temporal Server is excluded from those counters, so they cannot rank whole-engine memory. Cumulative allocations, live heap and RSS differ. Native throughput batches and equal-work resource cases have different iteration counts; their total CPU is not mixed.

Reliable execution and storage growth ​

The formal SQLite rerun reports Pulse + Durable reliable confirmation below, in ms as first/reuse medians; n counts complete ok samples only. Eino ordinary success has no equivalent per-node checkpoint measurement here, while Temporal is shown as a native-persistence baseline rather than collapsed into one ranking.

shape / NPulse + Durable first / reuse (ms)status
chain / 110.364200 / 7.471000ok=3
chain / 1054.447100 / 53.536500ok=3
chain / 100600.267700 / 603.486300ok=3
chain / 100012525.316300 / 14624.322000ok=3
chain / 10000— / —deadline=1, not_repeated=2
diamonds / 100012985.821400 / 13829.337400ok=3
wide / 100012879.575300 / 14727.901900ok=3
wide / 10000— / —deadline=1, not_repeated=2

Official sqlitestore v0.1.0 configures and reads back WAL/FULL; runtime Load/Save, CAS and local run ownership use that formal Store. Inspection connections, PRAGMA validation and setup costs are not engine graph construction. Process hard-kill is not power-loss testing; backup/restore, migration and distributed lease/fencing are not accepted here, and DB/WAL/SHM lengths are not cumulative physical writes.

Cross-process recovery ​

The formal recovery run uses chain/rounds=256, N=10/100/1000, confirmed prefixes 5/10/10, n=3 per configuration, with all 36 records completed. Pulse kills the host after confirmation and resumes in a new process; Eino saves a blob through active interrupt and resumes; Temporal separates runtime_kill from server_restart. These are confirmed boundaries without in-flight Activities/external effects and do not establish arbitrary exactly-once effects.

Engine / scenario / Nnwall s [min–max]operation ms [min–max]
eino / active_interrupt / 1030.049907 [0.046073–0.050180]24.372800 [21.061400–24.645800]
eino / active_interrupt / 10030.046845 [0.044777–0.054857]21.419600 [21.387700–25.076200]
eino / active_interrupt / 100030.134673 [0.130496–0.136944]103.711600 [103.558600–108.297300]
pulse / runtime_kill / 1030.072193 [0.065890–0.074435]19.992000 [19.426300–23.130100]
pulse / runtime_kill / 10030.335978 [0.303561–0.389495]286.402000 [276.070700–328.842300]
pulse / runtime_kill / 100039.886758 [9.355772–10.618498]9804.680500 [9303.068600–10548.256300]
temporal / runtime_kill / 1035.199157 [5.188746–5.213046]5134.301200 [5111.029900–5134.654700]
temporal / server_restart / 10310.167985 [0.713383–10.179320]9884.872200 [441.128800–9916.820000]
temporal / runtime_kill / 10038.647032 [8.632625–13.595738]8578.779300 [8567.382300–13526.297700]
temporal / server_restart / 10034.080621 [4.029154–4.241825]3795.921100 [3757.966300–3846.748700]
temporal / runtime_kill / 1000353.706356 [53.680285–53.717853]53615.510200 [53612.884800–53635.186500]
temporal / server_restart / 1000349.185665 [49.084596–49.220536]48907.995200 [48819.051800–48933.869500]

wall is controller recovery wall time; operation is the child-command scope, including Graph/Store or client reconstruction. Do not interchange them or rank wall time across semantics. Server-restart and worker-only recovery show counterintuitive ordering and broad ranges; without controlled diagnosis, no causal conclusion follows.

Data, reproduction and checks ​

The historical full-dimensional data remains in benchmarks/reports/2026-10-17-production/ with its compact CSV and identity. Current formal SQLite data is in sqlite-formal-20261023 summary.csv and identity.json. The external evidence root is go126-release-20261023/; raw records retain all failed and not-repeated states, while databases, logs and binaries stay outside the source repository.

The formal SQLite rerun independently reproduced checksums for 102 successful records and statistics for 57 groups; recovery completed 36/36. Its status is COMPLETED_WITH_ERRORS. It does not rewrite older Go 1.25 numbers as a Go 1.26 speedup or present this bounded collection as a full performance rerun.

Pinned sources: Eino v0.9.21, Temporal SDK v1.50.0, CLI v1.9.1.

Development API documentation · Go 1.26+ · MIT