Skip to main content
← Back to list
01Issue
BugShippedSwamp CLIPublic
AssigneesNone

Relationships

≡ duplicated by #3444↔ sibling #3443

#3407 workflow run search / history search parse every run record on every call, so their cost grows with all history ever kept

Opened by swamp_lord · 10/13/2026· Shipped 10/14/2026

Description

run_search (src/libswamp/workflows/run_search.ts) gets summaries for every workflow (findAllWorkflows then findAllRunsByWorkflowId). Through YamlWorkflowRunRepository.findAllSummariesByWorkflowId, that opens and YAML-parses every workflow-run-*.yaml in each workflow's directory. Only after that does it sort and apply --since, --status, --workflow and --limit. A search for the last hour still reads every run ever kept.

Each workflow already has a run index (workflow_run_index.ts), but this path doesn't use it. #3051 fixed the same pattern for run doctor.

It also hurts everything else on serve. The parsing ties up serve's single process, so unrelated requests queue behind it.

Measured on ops.swamp-club.com

Serve 20261013.004531.0-sha.1373120f, local filesystem datastore. Spans from serve's OTel traces.

  • History size: 13,226 run records (239 MB) across 41 workflows after 18 days. 5,196 are from one 5-minute reconcile workflow, 3,547 from an archive sync, and 2,448 from a webhook router at about 64 KB each, since each stores the full webhook payload.
  • Quiet server: swamp.workflow.run_search p50 2–4 s.
  • Under load (about 20 calls a minute from the dashboard, bots and CLI polling, 19:30–20:00 UTC on 2026-10-13):
    • run_search: 610 calls, max 115 s.
    • swamp.workflow.history.get: 630 calls, max 174 s. For a full run id this reads only one file (findGlobalById), so the time was spent waiting behind searches.
    • Worker data writes (POST /data/*): p50 1,264 s.
  • Consequence: a release build step failed with The operation was aborted due to timeout. Its final writeResource took 65.2 s on serve and returned 200, but the worker had given up at 60 s, so a write that succeeded was reported as failed.

Steps to reproduce

  1. A repo with about 10k run records across a few workflows.
  2. swamp workflow run search --since 1h takes seconds, and grows linearly with total history.
  3. Through serve: call it in a loop from a few clients while a remote worker writes data (context.writeResource). Watch POST /data/* latency climb.

Expected

  • Search and listing come from the index, and the time, status and workflow filters and the limit are applied before any run file is read.
  • Paged results, so a --limit 20 search reads about 20 records.
  • Cost grows with the result size, not with total history.

Related: #3051 (same fix for run doctor), #2865 (datastore rework), and the tiered-storage feature request filed alongside this.

02Bog Flow
✓OPEN✓TRIAGED✓IN PROGRESS✓SHIPPEDLINKED+ 7 MOREPR_MERGED+ 1 MORESESSION_SUMMARIZED

Shipped

10/14/2026, 4:15:21 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 linked duplicated by #344410/14/2026, 2:03:32 PM
hammz linked sibling of #344310/14/2026, 2:17:03 PM
Editable. Press Enter to edit.

swamp_lord commented 10/13/2026, 10:12:30 PM

The tiered-storage feature request mentioned above is #3408.

Sign in to post a ripple.