Skip to content

Use compact compiled mailboxes - #53

Merged
SandroMaglione merged 1 commit into
mainfrom
codex/compact-compiled-mailbox
Aug 9, 2026
Merged

Use compact compiled mailboxes#53
SandroMaglione merged 1 commit into
mainfrom
codex/compact-compiled-mailbox

Conversation

@SandroMaglione

Copy link
Copy Markdown
Member

Summary

  • replace Effect Queue with a compact FIFO for on-demand compiled statecharts
  • retain Effect Queue unchanged for persistent custom Machine.logic processes
  • preserve FIFO order, repeated idle wake-up, terminal send rejection, and stop arbitration with focused stress coverage

Changeset

  • Added or updated for a library or package-metadata change
  • Not required because this PR does not change src/ or package.json

Validation

  • pnpm check
  • Relevant example checks, when examples changed (not applicable)
  • Reviewed the automated type-performance report, when the public TypeScript API or inference changed (pnpm perf:types; public API unchanged)
  • Reviewed the automated runtime-performance report, when runtime behavior changed

Local paired runs show approximately 5-6% lower compiled-machine heap and 4-5% lower parent-child heap, with throughput and lifecycle effectively neutral to slightly positive.

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Type performance

Measured with TypeScript 6.0.3 and skipLibCheck=true.

Scenario Base PR Difference
Effect only 55 55 0 (0.0%)
Import effect-machine 55 55 0 (0.0%)
Machine.defineStates (3 states) 2,965 2,965 0 (0.0%)
Machine.make (3 states, 2 events) 8,715 8,715 0 (0.0%)
machine.handle (3 states, 2 transitions) 23,492 23,492 0 (0.0%)
machine.handle (depth 8) 117,075 117,075 0 (0.0%)
machine.handle (depth 12) 129,713 129,713 0 (0.0%)
machine.handle (depth 16) 145,055 145,055 0 (0.0%)
machine.handle (depth 24) 183,851 183,851 0 (0.0%)
machine.handle (wide depth 16) 214,189 214,189 0 (0.0%)
machine.handle (parallel/history/choice) 132,667 132,667 0 (0.0%)
machine.handle (4 successive calls) 128,674 128,674 0 (0.0%)
machine exact input/output/error/services 110,584 110,584 0 (0.0%)
execution adapter readiness 127,854 127,854 0 (0.0%)

Marginal instantiations are measured against the matching setup without that API call:

Scenario Base PR Difference
Import effect-machine 0 0 0
Machine.defineStates (3 states) 2,910 2,910 0 (0.0%)
Machine.make (3 states, 2 events) 5,742 5,742 0 (0.0%)
machine.handle (3 states, 2 transitions) 14,777 14,777 0 (0.0%)
machine.handle (depth 8) 109,601 109,601 0 (0.0%)
machine.handle (depth 12) 121,039 121,039 0 (0.0%)
machine.handle (depth 16) 135,181 135,181 0 (0.0%)
machine.handle (depth 24) 171,577 171,577 0 (0.0%)
machine.handle (wide depth 16) 202,224 202,224 0 (0.0%)
machine.handle (parallel/history/choice) 114,331 114,331 0 (0.0%)
machine.handle (4 successive calls) 113,703 113,703 0 (0.0%)
machine exact input/output/error/services 100,670 100,670 0 (0.0%)
execution adapter readiness 102,092 102,092 0 (0.0%)
Check times (informational)
Scenario Base PR
Effect only 0.03s 0.03s
Import effect-machine 0.03s 0.03s
Machine.defineStates (3 states) 0.11s 0.11s
Machine.make (3 states, 2 events) 0.17s 0.17s
machine.handle (3 states, 2 transitions) 0.24s 0.23s
machine.handle (depth 8) 0.56s 0.54s
machine.handle (depth 12) 0.58s 0.59s
machine.handle (depth 16) 0.63s 0.63s
machine.handle (depth 24) 0.74s 0.74s
machine.handle (wide depth 16) 0.79s 0.81s
machine.handle (parallel/history/choice) 0.65s 0.66s
machine.handle (4 successive calls) 0.60s 0.61s
machine exact input/output/error/services 0.53s 0.54s
execution adapter readiness 0.59s 0.61s

Type instantiations are the comparison metric. Check time varies with runner load and is informational only.

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Runtime performance

Median of 5 independent benchmark processes on AMD EPYC 7763 64-Core Processor with Node v24.18.0.

Pull request baseline

Scenario Effect Machine XState 5 XState 6 alpha
Plan counter transitions 100,701 transitions/s 136,436 transitions/s 123,960 transitions/s
Drain burst with terminal fence 82,879 increments/s 404,742 increments/s 112,903 increments/s
Drain burst with a change observer 61,125 increments/s 403,061 increments/s 112,416 increments/s
Lookup and send to one child 76,451 increments/s 399,794 increments/s 107,947 increments/s
Start and stop a machine 17,013 machines/s 184,502 machines/s 72,696 machines/s
Start and stop a parent with one child 5,587 families/s 67,395 families/s 27,020 families/s

Effect runtime reference points

Scenario Effect Machine Effect runtime primitives
Start and stop a raw compiled process 24,398 processes/s
Start and interrupt a suspended fiber 164,177 fibers/s
Start and stop a queue worker 113,688 workers/s
Start and stop an actor shell 104,297 actors/s
Start and stop two actor shells 58,268 families/s
Update an owner-only mutable snapshot 317,863,954 updates/s
Update a synchronized snapshot 1,435,925 updates/s
Create, resolve, and await a terminal latch 1,408,010 latches/s
Memory profile Effect Machine XState 5 XState 6 alpha Effect runtime primitives
Idle machine 8.4 KiB 3.8 KiB 6.1 KiB
Raw generic managed process 13.2 KiB
Raw compiled process 9.1 KiB
Two independent idle machines 16.0 KiB 7.3 KiB 11.8 KiB
Idle parent with one child 21.1 KiB 5.5 KiB 8.8 KiB
Parent with observed child registry 32.5 KiB
Parent with observed invoked child snapshots 21.3 KiB
Suspended Effect fiber 0.6 KiB
Effect queue with waiting fiber 2.8 KiB
Effect mailbox actor shell 3.2 KiB
Two Effect actor shells 6.9 KiB

Effect Machine change from base

Metric Base Base variability PR PR variability Difference
Plan counter transitions 100,056 transitions/s 3.2% MAD 100,701 transitions/s 0.5% MAD +0.6%
Drain burst with terminal fence 81,499 increments/s 3.1% MAD 82,879 increments/s 1.0% MAD +1.7%
Drain burst with a change observer 61,546 increments/s 3.6% MAD 61,125 increments/s 1.8% MAD -0.7%
Lookup and send to one child 74,506 increments/s 3.0% MAD 76,451 increments/s 1.7% MAD +2.6%
Start and stop a machine 16,299 machines/s 2.2% MAD 17,013 machines/s 2.8% MAD +4.4%
Start and stop a parent with one child 5,266 families/s 3.3% MAD 5,587 families/s 1.6% MAD +6.1%
Idle machine heap per unit 8.8 KiB 0.0% MAD 8.4 KiB 0.0% MAD -5.2%
Raw generic managed process heap per unit 13.2 KiB 0.0% MAD 13.2 KiB 0.0% MAD +0.0%
Raw compiled process heap per unit 9.6 KiB 0.0% MAD 9.1 KiB 0.1% MAD -5.5%
Two independent idle machines heap per unit 17.1 KiB 0.0% MAD 16.0 KiB 0.0% MAD -6.2%
Idle parent with one child heap per unit 22.1 KiB 0.0% MAD 21.1 KiB 0.0% MAD -4.7%
Parent with observed child registry heap per unit 33.6 KiB 0.0% MAD 32.5 KiB 0.0% MAD -3.3%
Parent with observed invoked child snapshots heap per unit 22.3 KiB 0.0% MAD 21.3 KiB 0.0% MAD -4.5%

Effect runtime reference change from base

Metric Base Base variability PR PR variability Difference
Start and stop a raw compiled process 23,970 processes/s 3.1% MAD 24,398 processes/s 1.0% MAD +1.8%
Start and interrupt a suspended fiber 164,989 fibers/s 0.8% MAD 164,177 fibers/s 1.6% MAD -0.5%
Start and stop a queue worker 114,469 workers/s 0.4% MAD 113,688 workers/s 0.5% MAD -0.7%
Start and stop an actor shell 105,955 actors/s 1.4% MAD 104,297 actors/s 1.4% MAD -1.6%
Start and stop two actor shells 65,928 families/s 1.8% MAD 58,268 families/s 1.4% MAD -11.6%
Update an owner-only mutable snapshot 316,957,211 updates/s 0.0% MAD 317,863,954 updates/s 0.0% MAD +0.3%
Update a synchronized snapshot 1,500,353 updates/s 1.0% MAD 1,435,925 updates/s 0.9% MAD -4.3%
Create, resolve, and await a terminal latch 1,469,281 latches/s 0.1% MAD 1,408,010 latches/s 1.0% MAD -4.2%
Versions and interpretation
  • Effect Machine: 0.3.0
  • XState 5: 5.32.5
  • XState 6 alpha: 6.0.0-alpha.27
  • Effect runtime primitives: 4.0.0-beta.105

Higher throughput is better; lower heap is better. Variability is the median absolute deviation across independent processes, relative to their median. Runtime measurements on shared GitHub-hosted hardware remain informational, so small differences should be confirmed across multiple workflow runs.

@SandroMaglione
SandroMaglione force-pushed the codex/compact-compiled-mailbox branch from 475b8b3 to ac9805f Compare August 9, 2026 03:36
@SandroMaglione
SandroMaglione merged commit 1fa7b71 into main Aug 9, 2026
9 checks passed
@SandroMaglione
SandroMaglione deleted the codex/compact-compiled-mailbox branch August 9, 2026 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant