Skip to content

Measure the pooling fix through production - it's ~1.2x, correcting the comments - #16

Merged
chrismuench merged 1 commit into
mainfrom
perf/prove-pooling
Jul 20, 2026
Merged

Measure the pooling fix through production - it's ~1.2x, correcting the comments#16
chrismuench merged 1 commit into
mainfrom
perf/prove-pooling

Conversation

@chrismuench

Copy link
Copy Markdown
Collaborator

Follow-up to #15. Taking that pooling fix to its evidence showed my own commit overstated it.

#15 corrected DI to register the pooled factory and asserted the resolved type is pooled — but a type assertion isn't a throughput measurement, and the comments claimed pooling was "the difference between about 1,000 and several thousand writes/sec."

ProductionPoolingBenchmarkTests runs the ingest write pattern through the real AddDispatchData registration vs a non-pooled equivalent. On SQLite, 16 writers:

path writes/sec
pooled (production) 9,000–11,900
non-pooled (pre-fix) 7,600–8,800

~1.1×–1.5×. Real, but not the headline.

The ~3.5× jump earlier on the branch (998→3,509) was the WAL synchronous=NORMAL pragma, which is I/O-bound and dominates — SQLite serialises writers on one lock regardless of context allocation. I'd conflated the two fixes. Production before the pooling fix already had the synchronous fix (shipped in #14, applies to every path), so it was never at ~1,000/sec — it was ~8,000. Pooling took it to ~9,500.

Both comments corrected to the measured figure and to distinguish the two fixes. The benchmark ships opt-in (DISPATCH_BENCH) as evidence and a regression guard.

🤖 Generated with Claude Code

…t 2-3x

Following the pooling fix (#15) to its evidence exposed that my own commit overstated
it. The fix corrected DI to register the pooled context factory and added a test that
the resolved factory is the pooled TYPE - but a type assertion is not a throughput
number, and the comments claimed pooling was "the difference between about 1,000 and
several thousand concurrent writes per second."

ProductionPoolingBenchmarkTests runs the ingest write pattern through the real
AddDispatchData registration - the exact ILogRepository/ICounterRepository the service
resolves - and against a hand-built non-pooled equivalent. Measured on SQLite, 16
writers: pooled 9,000-11,900/sec, non-pooled 7,600-8,800/sec. Roughly 1.1x-1.5x. Real,
but not the headline the comments claimed.

The ~3.5x jump earlier this branch (998 -> 3,509/sec) was the WAL synchronous=NORMAL
pragma (ProviderConnectionInterceptor), which is I/O-bound and dominates because SQLite
serialises writers on one lock regardless of context allocation. I conflated the two:
pooling is the small CPU-bound saving on top, not the big one. Production before the
pooling fix already had the synchronous fix (it shipped in #14 and applies to every
path), so it was never at ~1,000/sec - it was around 8,000. The pooling fix took it to
~9,500.

Corrected both comments to the measured figure and to distinguish the two fixes.
Pooling is still worth registering - it is free once the factory exists and it is what
makes the test and production paths measure the same thing - but the reason is
correctness of measurement, not the speed-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chrismuench
chrismuench merged commit 305dc2f into main Jul 20, 2026
7 checks passed
@chrismuench
chrismuench deleted the perf/prove-pooling branch July 20, 2026 21:50
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