Skip to content

perf: stored procedure for batch commands (appendBatch single round-trip) #79

Description

@PaulGrimshaw

Problem

append(AppendCommand[]) with per-command conditions currently uses appendBatch — a multi-round-trip path:

  1. BEGIN
  2. Advisory lock acquisition (1 query)
  3. getHighWaterMark (1 query)
  4. COPY events to main table
  5. CREATE TEMP TABLE + COPY conditions
  6. JOIN-based condition check
  7. currval
  8. pg_notify
  9. COMMIT

~10 round-trips per call. Benchmarked at 2,600 ev/s for 500 commands × 1 event each (T16).

Compare: single-command appendViaFunction does everything in 1 round-trip via stored procedure — benchmarked at 22,000 ev/s (T1) for single-event conditional appends.

Proposed solution

A stored procedure that accepts arrays of commands and does the full loop server-side:

  1. Acquire advisory locks (already done in SP for single commands)
  2. INSERT all events via unnest/generate_subscripts
  3. Per-command condition check against pre-insert snapshot (highWaterMark pattern)
  4. RAISE on first violation with command index
  5. pg_notify + return last position

Single round-trip. Expected gain: 5-8x for batch commands with per-event conditions.

Benchmark baseline (from event-store-bench T16)

Cmds/append Current ev/s p50
1 811 6ms
10 1,619 45ms
50 2,000 271ms
100 2,160 524ms
500 2,600 2,148ms

Target: match or approach T1's 22K ev/s at 1 cmd, and scale with batch size.

Context

  • Discovered via T14/T15/T16 scenarios in packages/event-store-bench
  • COPY_THRESHOLD raised to 10K in feat: event-store-bench + raise COPY_THRESHOLD to 10K #78 based on T15 crossover analysis
  • The stored procedure path already exists for single commands — this extends it to handle multiple commands

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions