Skip to content

feat(rivetkit): client-side KV preloading and startup metrics#4493

Merged
NathanFlurry merged 5 commits intomainfrom
ralph/actor-startup-kv-preload-client-side
Mar 24, 2026
Merged

feat(rivetkit): client-side KV preloading and startup metrics#4493
NathanFlurry merged 5 commits intomainfrom
ralph/actor-startup-kv-preload-client-side

Conversation

@NathanFlurry
Copy link
Copy Markdown
Member

Summary

  • Preload actor startup KV data client-side to reduce round-trips from 5+ to 2 (1 persist check + 1 parallel preload for existing actors)
  • Add comprehensive startup metrics to /inspector/metrics endpoint covering all internal and user-facing startup phases
  • Batch new-actor init writes (persist data, queue metadata, inspector token) into a single kvBatchPut via WriteCollector
  • No engine or protocol changes required. All preloading happens in TypeScript runtime.

Key design decisions

  • Existing actors: 1 RT to check persist data, then 1 RT with parallel kvGet + 3x kvListPrefix to preload everything else
  • New actors: No preloading (nothing to preload), just 1 RT check + 1 RT write
  • Startup metrics split into startup_internal_* (framework) and startup_user_* (callbacks) with flat key structure matching existing metrics format
  • KV round-trip counter tracks every KV call during the startup window

Test plan

  • PreloadMap unit tests (29 tests)
  • WriteCollector unit tests (4 tests)
  • Driver test for /inspector/metrics startup fields (12 test runs across all encodings/client types)
  • TypeScript type checks pass (no new errors)

🤖 Generated with Claude Code

Preload actor startup KV data client-side to reduce round-trips:
- Existing actors: 1 RT (check persist) + 1 RT (parallel preload) = 2 RTs
- New actors: 1 RT (check persist) + 1 RT (write initial state) = 2 RTs
- Previously: 5+ sequential RTs during startup

Add comprehensive startup metrics to /inspector/metrics:
- Internal timing: checkPersistData, preloadKv, instantiate, loadState,
  restoreConnections, initQueue, initInspectorToken, flushWrites,
  setupDatabaseClient, initAlarms, onBeforeActorStart
- User timing: createState, onCreate, onWake, createVars, dbMigrate
- KV round-trip counter and total startup time

WriteCollector batches new-actor init writes (persist data, queue
metadata, inspector token) into a single kvBatchPut call.

PreloadMap provides binary-search-based lookups for preloaded KV data
with three-way return semantics (found/not-found/not-preloaded).

SQLite VFS preload entries are passed through to createActorKvStore
for cache hits during database initialization.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4493 March 24, 2026 09:40 Destroyed
@railway-app
Copy link
Copy Markdown

railway-app bot commented Mar 24, 2026

🚅 Deployed to the rivet-pr-4493 environment in rivet-frontend

Service Status Web Updated (UTC)
frontend-inspector 🕒 Building (View Logs) Web Mar 24, 2026 at 11:01 am
frontend-cloud 🕒 Building (View Logs) Web Mar 24, 2026 at 11:01 am
kitchen-sink 🕒 Building (View Logs) Web Mar 24, 2026 at 11:01 am
website 😴 Sleeping (View Logs) Web Mar 24, 2026 at 9:54 am
mcp-hub ✅ Success (View Logs) Web Mar 24, 2026 at 9:41 am
ladle ❌ Build Failed (View Logs) Web Mar 24, 2026 at 9:41 am

@claude
Copy link
Copy Markdown

claude bot commented Mar 24, 2026

hello world

Log every SQL query at debug level with duration and the number of KV
operations it triggered. Covers both raw db() and drizzle db() paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4493 March 24, 2026 09:53 Destroyed
- Replace 3-way Uint8Array|null|undefined return with PreloadHit struct
- Extract createPreloadMap() shared builder, dedup from engine driver
- Export hasPrefix/binarySearchExists, remove duplicates in actor-driver
- Remove `as any` cast via StartupTimingKey mapped type
- Use try/finally for KV round-trip guard save/restore
- Move kvStoreRef from closure to per-client WeakMap in db providers
- Add startup logging convention to CLAUDE.md
- Fix missing newline at EOF in actor-driver.ts
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4493 March 24, 2026 10:12 Destroyed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4493 March 24, 2026 10:16 Destroyed
- Change startup metric types from "counter" to "gauge" (point-in-time values)
- Fix stale preload data bug: clear preload before migrations, not after
- Add pauseKvGuard option to #measureStartup, collapse guard boilerplate
- Use perf internal/perf user log prefixes matching CLAUDE.md convention
- Add comments noting preload hits are not tracked in KV metrics

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4493 March 24, 2026 11:00 Destroyed
@NathanFlurry NathanFlurry merged commit a9fb68d into main Mar 24, 2026
11 of 19 checks passed
@NathanFlurry NathanFlurry deleted the ralph/actor-startup-kv-preload-client-side branch March 24, 2026 11:02
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