Skip to content

perf: reduce Temporal RPCs with run status cache and lazy frontend loading | ENG-139 & ENG-200#293

Merged
LuD1161 merged 4 commits intomainfrom
perf/optimization-and-cleanup
Feb 16, 2026
Merged

perf: reduce Temporal RPCs with run status cache and lazy frontend loading | ENG-139 & ENG-200#293
LuD1161 merged 4 commits intomainfrom
perf/optimization-and-cleanup

Conversation

@LuD1161
Copy link
Copy Markdown
Contributor

@LuD1161 LuD1161 commented Feb 16, 2026

Summary

  • Run status cache: Cache terminal workflow run statuses (COMPLETED, FAILED, CANCELLED, TERMINATED, TIMED_OUT) in PostgreSQL to skip expensive Temporal gRPC calls for finished runs. Fire-and-forget caching on first Temporal read; subsequent reads hit DB only.
  • Lazy page loading: Convert all page imports to React.lazy() with Suspense, reducing initial bundle size
  • Paginated runs: Frontend fetches only 5 runs initially with "Load more" button (20 at a time), reducing API payload
  • Design mode optimization: Skip runs fetch when workflow builder opens in design mode
  • Schedule fetch dedup: 5-second cooldown + inflight deduplication for schedule fetches
  • Lightweight workflow list: New /workflows/summary endpoint returns workflow metadata without full graph data
  • Shared TERMINAL_STATUSES: Canonical constant in @shipsec/shared replaces 5+ duplicated arrays
  • Dark mode: Adjust --muted/--accent HSL values, add scrollbar-hide utility and highlight-fade animation

Performance Impact

1. Temporal RPC Reduction (Run Status Cache)

Scenario Before After Improvement
Terminal run status check 1 Temporal gRPC call (~50-200ms) 1 DB read (~2-5ms) ~90-97% faster
Workflow list with N terminal runs N Temporal calls 0 Temporal calls N fewer RPCs
getRunStatus() for completed run Temporal describe + trace counts DB read only (+ 1 trace count) 2-3 fewer queries
First call for terminal run 1 Temporal call + fire-and-forget cache write Same (one-time cost) Amortized to 0

Real-world estimate: A workflow list page with 50 runs where 45 are terminal goes from 45 Temporal RPCs (~4.5-9s)0 Temporal RPCs (~0.1-0.2s) for status resolution.

2. Frontend Bundle / Load Time

Metric Before After Improvement
Initial JS bundle All pages eagerly loaded Only active page loaded ~60-70% smaller initial load
Page components 15 direct imports 15 React.lazy() imports Code-split per route
StrictMode in prod Double-renders in production Dev-only StrictMode ~2x fewer renders in prod

3. API Call Reduction

Page/Feature Before After Improvement
Workflow list page GET /workflows (full graph data) GET /workflows/summary (metadata only) ~80-90% smaller payload
Artifact Library, Schedules, Webhooks pages Each calls workflows.list() Each calls workflows.listSummary() Same savings
Workflow Builder (design mode) Fetches runs on open Skips runs fetch entirely 1 fewer API call
Initial runs load 50 runs (default limit) 5 runs (INITIAL_LIMIT) 90% less data
Schedule fetches No dedup, fetches on every render 5s cooldown + inflight dedup ~5-10x fewer calls
Component store Fetches every mount Skip if already loaded Eliminates redundant fetches

4. Payload Size Estimates

Endpoint Before (per workflow) After (per workflow) Reduction
/workflows response ~5-50KB (includes full graph JSON) N/A -
/workflows/summary response N/A ~200-500 bytes ~95-99%
/workflows/runs (initial) 50 runs × ~2KB = ~100KB 5 runs × ~2KB = ~10KB ~90%

5. Polling Efficiency

Behavior Before After Improvement
Run polling Polls all runs every interval Only polls non-terminal runs Fewer active polls
Run list refresh Fetches all 50 again Smart refresh with current cache size Less redundant data
isRunLive check Duplicated in 3+ files Shared utility from executionRuns.ts Consistency + correctness

Net Effect (Estimated)

Metric Estimated Gain
Workflow list page load 3-10x faster (for users with many completed runs)
Initial app load (TTI) ~40-60% faster (lazy loading)
Backend Temporal load ~80-95% reduction in gRPC calls at steady state
Network transfer per session ~50-70% less data transferred

Test plan

  • New run-status-cache.spec.ts tests covering cache-hit, cache-miss, and Temporal-not-found scenarios
  • Existing workflows.service.spec.ts updated with cacheTerminalStatus mock
  • Manual: Verify workflow list loads fast with summary endpoint
  • Manual: Verify "Load more runs" pagination in workflow builder
  • Manual: Verify terminal runs don't trigger Temporal calls (check backend logs)
  • Manual: Verify dark mode colors render correctly

Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
…ading

Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
- Adjust dark mode --muted and --accent HSL values for better contrast
- Add scrollbar-hide utility class
- Add highlight-fade animation for new findings in security dashboard

Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cf4e09a7d6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread frontend/src/features/workflow-builder/WorkflowBuilder.tsx Outdated
Comment thread frontend/src/features/workflow-builder/hooks/useWorkflowSchedules.ts Outdated
…kflow

- navigate('/builder') → navigate('/') on workflow load failure (/builder doesn't exist)
- Scope inflightRef dedup to current workflowId to prevent stale schedule data when switching workflows

Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
@LuD1161 LuD1161 changed the title perf: reduce Temporal RPCs with run status cache and lazy frontend loading perf: reduce Temporal RPCs with run status cache and lazy frontend loading | ENG-139 & ENG-200 Feb 16, 2026
@LuD1161 LuD1161 merged commit 8e76e10 into main Feb 16, 2026
3 checks passed
@LuD1161 LuD1161 deleted the perf/optimization-and-cleanup branch February 16, 2026 22:51
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