Skip to content

perf: denormalize step_count and remove labels JSON fallback#132

Merged
coji merged 3 commits intomainfrom
refactor/storage-cohesion-and-join
Mar 16, 2026
Merged

perf: denormalize step_count and remove labels JSON fallback#132
coji merged 3 commits intomainfrom
refactor/storage-cohesion-and-join

Conversation

@coji
Copy link
Owner

@coji coji commented Mar 16, 2026

Summary

#124: Remove LEFT JOIN from getRun/getRuns

Before: Every getRun()/getRuns() did LEFT JOIN durably_steps + COUNT + GROUP BY to compute stepCount. With preserveSteps: false (default), steps are deleted on terminal state, so this JOIN was paying cost for data that usually doesn't exist.

After: step_count is a denormalized column on durably_runs, incremented atomically in persistStep alongside current_step_index. getRun/getRuns is now a simple SELECT * FROM durably_runs — no JOIN, no GROUP BY, no COUNT.

Labels JSON fallback removed

The getRuns label filter had an OR clause: EXISTS (indexed table) OR json_extract(...). The JSON fallback was for "atomicity safety" but the indexed table is always populated in the same transaction as the run. Removed the fallback — cleaner query plan, indexed table is sole source of truth.

Changes

File Change
schema.ts Add step_count: number to RunsTable
migrations.ts Add step_count column (DEFAULT 0) to v1
storage.ts persistStep: increment step_count via sql\step_count + 1``
storage.ts getRun/getRuns: simple SELECT, no JOIN
storage.ts getRuns labels: remove JSON fallback, EXISTS only
storage.ts rowToRun: read step_count directly from row
storage.ts Remove unused SqlBool import
migration-consolidated.test.ts Assert step_count column exists

Closes #124

🤖 Generated with Claude Code

Summary by CodeRabbit

リリースノート

  • 新機能

    • 実行内のステップ追跡機能を追加しました。各実行は、完了したステップ数をカウントしてトラッキングできるようになります。
  • テスト

    • ステップカウント機能の検証テストを追加しました。

#124: getRun/getRuns no longer LEFT JOIN durably_steps for step_count.
Instead, step_count is a denormalized column on durably_runs, incremented
atomically in persistStep alongside current_step_index. This eliminates
the JOIN + COUNT + GROUP BY overhead on every run query.

Also removed the labels JSON fallback (OR with json_extract/JSONB ->>)
from getRuns label filtering. The indexed durably_run_labels table is
the sole source of truth — the JSON column remains for backwards-compat
reads but is no longer queried for filtering.

#131 (partial): Removed SqlBool import and simplified rowToRun signature
(no more step_count override).

Migration consolidated into v1 (no backward compatibility needed).

Closes #124

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

vercel bot commented Mar 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
durably-demo Ready Ready Preview Mar 16, 2026 0:25am
durably-demo-vercel-turso Ready Ready Preview Mar 16, 2026 0:25am

@coderabbitai
Copy link

coderabbitai bot commented Mar 16, 2026

Warning

Rate limit exceeded

@coji has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 15 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bb4ecaec-e71e-4d74-b52b-01636b85fdcf

📥 Commits

Reviewing files that changed from the base of the PR and between 6c011ba and b3f9725.

📒 Files selected for processing (15)
  • .claude/skills/doc-check/scripts/find-stale.sh
  • CHANGELOG.md
  • examples/fullstack-react-router/app/routes/_index/dashboard.tsx
  • examples/fullstack-vercel-turso/app/routes/_index/dashboard.tsx
  • examples/spa-react-router/app/routes/_index/dashboard.tsx
  • examples/spa-vite-react/src/components/dashboard.tsx
  • packages/durably-react/tests/client/use-runs.test.tsx
  • packages/durably-react/tests/types.test.ts
  • packages/durably/src/migrations.ts
  • packages/durably/src/schema.ts
  • packages/durably/src/storage.ts
  • packages/durably/tests/node/migration-consolidated.test.ts
  • packages/durably/tests/shared/storage.shared.ts
  • website/api/create-durably.md
  • website/api/durably-react/types.md
📝 Walkthrough

Walkthrough

durably_runs テーブルに step_count カラムを追加し、スキーマを拡張しました。ストレージレイヤーで step_count を初期化・更新するロジックを追加し、ステップカウント取得時の左結合クエリを削除しました。

Changes

Cohort / File(s) Summary
マイグレーション & スキーマ
packages/durably/src/migrations.ts, packages/durably/src/schema.ts
durably_runs テーブルに step_count 非NULL整数カラム(デフォルト値 0)を追加、RunsTable インターフェースを拡張。
ストレージロジック
packages/durably/src/storage.ts
新規ラン作成時に step_count: 0 を初期化、persistStep での step_count インクリメント機能を追加。getRun/getRuns クエリから durably_steps との左結合とグループ化を削除。ラベルフィルタリングをシンプル化し JSON フォールバック削除。rowToRun 関数シグネチャを更新。
テスト
packages/durably/tests/node/migration-consolidated.test.ts
マイグレーション後の runs テーブルに step_count カラムが存在することを検証する assertion を追加。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 Step count は denormalize され、
Join の重荷は消え去りて、
クエリは軽く、素早く舞う—
データベースの心、喜びて!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: denormalizing step_count and removing the labels JSON fallback, which directly address the PR objectives.
Linked Issues check ✅ Passed All requirements from issue #124 are met: step_count denormalized into durably_runs, persistStep increments it atomically, getRun/getRuns avoid LEFT JOIN, and labels JSON fallback is removed.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue objectives; no unrelated modifications are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/storage-cohesion-and-join
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

The field only counts completed steps (not failed/cancelled), so the
name should be precise. No backward compatibility needed.

Renamed across: schema, migrations, storage, Run type, tests, examples,
docs, and changelog.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coji coji merged commit b4fc102 into main Mar 16, 2026
5 checks passed
@coji coji deleted the refactor/storage-cohesion-and-join branch March 16, 2026 12:27
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.

perf: getRun/getRuns always JOINs durably_steps for stepCount

1 participant