Skip to content

Let Effect schedule machine event loops - #37

Merged
SandroMaglione merged 1 commit into
mainfrom
codex/experiment-effect-scheduler-yield
Aug 8, 2026
Merged

Let Effect schedule machine event loops#37
SandroMaglione merged 1 commit into
mainfrom
codex/experiment-effect-scheduler-yield

Conversation

@SandroMaglione

Copy link
Copy Markdown
Member

Summary

  • Let Effect's runtime scheduler control cooperative yielding while draining machine event bursts.
  • Remove the forced scheduler turn after every processed or ignored event.
  • Verify that scheduler-configured fairness still allows concurrent stops and invoked children to progress during sustained backlogs.

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
  • Reviewed the automated type-performance report, when the public TypeScript API or inference changed
  • Reviewed the automated runtime-performance report, when runtime behavior changed

Local validation also included pnpm perf:types and five interleaved benchmark processes comparing main, a fixed 32-event yield cadence, and Effect scheduler-only behavior. Scheduler-only behavior matched cadence 32 while improving the event throughput scenarios by approximately 54–62% over main.

@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,731 8,731 0 (0.0%)
machine.handle (3 states, 2 transitions) 23,634 23,634 0 (0.0%)
machine.handle (depth 8) 113,023 113,023 0 (0.0%)
machine.handle (depth 12) 125,661 125,661 0 (0.0%)
machine.handle (depth 16) 141,003 141,003 0 (0.0%)
machine.handle (depth 24) 179,799 179,799 0 (0.0%)
machine.handle (wide depth 16) 210,137 210,137 0 (0.0%)
machine.handle (parallel/history/choice) 128,876 128,876 0 (0.0%)
machine.handle (4 successive calls) 129,498 129,498 0 (0.0%)
machine exact input/output/error/services 107,371 107,371 0 (0.0%)
execution adapter readiness 122,890 122,890 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,758 5,758 0 (0.0%)
machine.handle (3 states, 2 transitions) 14,903 14,903 0 (0.0%)
machine.handle (depth 8) 105,546 105,546 0 (0.0%)
machine.handle (depth 12) 116,984 116,984 0 (0.0%)
machine.handle (depth 16) 131,126 131,126 0 (0.0%)
machine.handle (depth 24) 167,522 167,522 0 (0.0%)
machine.handle (wide depth 16) 198,169 198,169 0 (0.0%)
machine.handle (parallel/history/choice) 110,514 110,514 0 (0.0%)
machine.handle (4 successive calls) 114,497 114,497 0 (0.0%)
machine exact input/output/error/services 95,819 95,819 0 (0.0%)
execution adapter readiness 96,968 96,968 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.09s 0.09s
Machine.make (3 states, 2 events) 0.15s 0.14s
machine.handle (3 states, 2 transitions) 0.22s 0.22s
machine.handle (depth 8) 0.47s 0.46s
machine.handle (depth 12) 0.53s 0.51s
machine.handle (depth 16) 0.54s 0.53s
machine.handle (depth 24) 0.63s 0.61s
machine.handle (wide depth 16) 0.68s 0.68s
machine.handle (parallel/history/choice) 0.57s 0.57s
machine.handle (4 successive calls) 0.53s 0.53s
machine exact input/output/error/services 0.49s 0.48s
execution adapter readiness 0.51s 0.51s

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 27,376 transitions/s 133,039 transitions/s 121,363 transitions/s
Drain burst with terminal fence 18,444 increments/s 398,728 increments/s 110,674 increments/s
Drain burst with a change observer 16,719 increments/s 395,699 increments/s 110,056 increments/s
Lookup and send to one child 16,352 increments/s 394,658 increments/s 105,734 increments/s
Start and stop a machine 6,296 machines/s 183,824 machines/s 72,696 machines/s
Start and stop a parent with one child 2,535 families/s 67,622 families/s 26,503 families/s
Memory profile Effect Machine XState 5 XState 6 alpha
Idle machine 25.0 KiB 3.8 KiB 6.1 KiB
Idle parent with one child 74.8 KiB 5.5 KiB 8.8 KiB

Effect Machine change from base

Metric Base Base variability PR PR variability Difference
Plan counter transitions 26,698 transitions/s 3.3% MAD 27,376 transitions/s 2.5% MAD +2.5%
Drain burst with terminal fence 15,432 increments/s 4.4% MAD 18,444 increments/s 0.4% MAD +19.5%
Drain burst with a change observer 14,484 increments/s 0.2% MAD 16,719 increments/s 2.0% MAD +15.4%
Lookup and send to one child 14,269 increments/s 2.8% MAD 16,352 increments/s 1.5% MAD +14.6%
Start and stop a machine 6,230 machines/s 1.4% MAD 6,296 machines/s 0.8% MAD +1.1%
Start and stop a parent with one child 2,583 families/s 2.3% MAD 2,535 families/s 0.1% MAD -1.9%
Idle machine heap per unit 25.0 KiB 0.0% MAD 25.0 KiB 0.0% MAD +0.0%
Idle parent with one child heap per unit 74.8 KiB 0.0% MAD 74.8 KiB 0.0% MAD -0.0%
Versions and interpretation
  • Effect Machine: 0.3.0
  • XState 5: 5.32.5
  • XState 6 alpha: 6.0.0-alpha.27

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 merged commit 995bb3b into main Aug 8, 2026
9 checks passed
@SandroMaglione
SandroMaglione deleted the codex/experiment-effect-scheduler-yield branch August 8, 2026 08:45
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