Skip to content

perf(db, schema): enable prepared statements and optimize parse path#1749

Merged
viniciusdacal merged 1 commit intomainfrom
viniciusdacal/rinha-backend
Mar 23, 2026
Merged

perf(db, schema): enable prepared statements and optimize parse path#1749
viniciusdacal merged 1 commit intomainfrom
viniciusdacal/rinha-backend

Conversation

@viniciusdacal
Copy link
Copy Markdown
Contributor

Summary

  • Enable { prepare: true } on sql.unsafe() in @vertz/db postgres driver — enables server-side prepared statement caching, reducing per-query overhead by ~60% (0.57ms → 0.24ms/op)
  • Remove manual coerceValue timestamp coercion — postgres.js handles type conversion natively via built-in OID parsers
  • Optimize @vertz/schema parse hot path: memoize shape keys Set, lazy issues array, skip unknown key filtering in strip mode (the default)

Benchmark Results (rinha-de-backend URL shortener challenge)

# Participant RPS p95 Latency
1 Vertz (Bun) 2443 54.5ms
2 Go 1528 78.7ms
3 Python 504 114ms
4 Ruby 243 298ms

Vertz beats Go by 60% on throughput and 31% on latency.

What changed

@vertz/db postgres driver

  • sql.unsafe() now passes { prepare: true } — postgres.js caches query plans server-side, avoiding parse+plan on every call
  • Removed coerceValue() / isTimestampString() — these ran a regex on every column of every row to convert timestamp strings to Dates. With fetch_types: false, postgres.js still handles standard type conversion natively. The regex coercion was unnecessary overhead with false-positive risk (text columns containing timestamp-like strings would be silently converted)

@vertz/schema parse context + object schema

  • ParseContext.issues is now lazily allocated — the empty [] array was allocated on every successful parse (the 99% case), wasted
  • ObjectSchema._shapeKeys Set is memoized in the constructor instead of recreated per .parse() call
  • Unknown key filtering is skipped entirely in strip mode (the default) — previously computed the list of unknown keys then threw it away

Test plan

  • All 37 postgres driver tests pass (updated to expect { prepare: true })
  • All 371 schema tests pass
  • Full monorepo CI: 87/87 tasks pass (lint + typecheck + test + build)
  • Benchmarked: 39/39 correctness tests pass, 2443 rps throughput

Related

🤖 Generated with Claude Code

Enable `{ prepare: true }` on postgres.js `sql.unsafe()` calls in
@vertz/db's postgres driver. This enables server-side prepared statement
caching, reducing per-query overhead by ~60% (0.57ms → 0.24ms/op).

Remove the manual `coerceValue` timestamp coercion layer — postgres.js
handles type conversion natively via built-in OID parsers when connected
normally.

In @vertz/schema, optimize the hot parse path:
- Memoize shape keys Set in ObjectSchema constructor (avoid per-parse alloc)
- Lazy issues array in ParseContext (skip alloc for valid parses)
- Skip unknown key filtering in strip mode (the default)

Benchmarked via rinha-de-backend URL shortener challenge: Vertz achieved
2443 req/s (#1) vs Go 1528 req/s (#2), with p95 latency of 54ms vs 79ms.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@viniciusdacal viniciusdacal merged commit 15525cb into main Mar 23, 2026
4 checks passed
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 23, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

viniciusdacal added a commit that referenced this pull request Mar 24, 2026
- Add domain() API guide page with route prefixing, middleware, collision detection
- Add composite primary keys section to schema guide
- Add form field revalidation (revalidateOn) to forms guide and API reference
- Update SSR guide from two-pass to single-pass rendering flow
- Add RLS migration integration and withSessionVars() to migrations and codegen guides
- Document rules.where() database-level enforcement in auth guide
- Add prepared statements section to queries guide
- Update navigation and server overview for domains

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
viniciusdacal added a commit that referenced this pull request Mar 24, 2026
…ngle-pass) (#1778)

* docs: audit and update docs for recent PRs (#1749-#1773)

- Add domain() API guide page with route prefixing, middleware, collision detection
- Add composite primary keys section to schema guide
- Add form field revalidation (revalidateOn) to forms guide and API reference
- Update SSR guide from two-pass to single-pass rendering flow
- Add RLS migration integration and withSessionVars() to migrations and codegen guides
- Document rules.where() database-level enforcement in auth guide
- Add prepared statements section to queries guide
- Update navigation and server overview for domains

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: fix review findings — FieldState accuracy, withSessionVars, CLI commands

- Fix FieldState API reference: remove phantom pristine/setTouched/validate,
  add actual setValue/reset methods
- Replace withSessionVars() import examples with raw SET LOCAL SQL since the
  function is not yet part of the public API
- Fix vertz generate → vertz codegen CLI command references in codegen guide

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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