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

Relationships

#3893 v3 long silent waits: crash recovery runs ~24 s with no output, data prune is silent 6-10 s in log mode, and a lagging read hangs ~112 s when Litestream's listing is cut (found by #3756)

Opened by stack72 · 10/24/2026· Shipped 10/25/2026

Background

swamp's datastore rework (tracking: swamp-club#2865) has finished solo mode: v3 datastores on filesystem, S3 and GCS, with one writer at a time. The Phase 4 dogfood (swamp-club#3756) found three places where a v3 command goes quiet for long enough to look hung. Nothing is lost in any of them, but a user, or an agent waiting on the command, can't tell a slow command from a stuck one. This is the last code item before Phase 4 closes.

1. Crash recovery runs silently for about 24 s on a populated checkout

What happens. After a writer is killed between storing its content and committing it, the next command in that checkout recovers the dropped work. On a populated checkout (14,426 files under .swamp/) that took 23.75 s and 25.09 s, with nothing printed. The command after it took 0.7 s. In a small repo it took 2.2 s, of which about 1.45 s sat inside swamp.cli outside every named span. Buckets showed the same pattern, at about 25 s. A kill that lands after the commit costs nothing.

Repro. ~/dogfood-3756: on a clone of a populated v3 repo, run a method (slowblob) that writes 5 MB and then sleeps, and SIGKILL it after the content is written but before the commit. Then time the next swamp model method run.

Measured on ea2a36f51 only: re-measure on current main first, since #3803 changed the read model.

Expected. Recovery removes unowned files newer than the marker, which should cost a walk plus lookups. 24 s that grows with the checkout's size suggests per-file lookups or reads.

  • Profile it and fix what the profile shows.
  • Whatever remains prints a progress line on stderr ("Recovering work an interrupted command left in this checkout…"), so the pause is explained. --json stdout stays clean.

2. data prune stays silent for 6–10 s in log mode

What happens. Since swamp-club#3759, a v3 command's output waits for its root to commit. That includes the status lines of commands that used to stream them. Time to first output on the populated bucket repos:

Command S3 GCS
data prune 9.7 s 6.2 s
data gc 4.2 s 3.4 s
run gc 3.7 s 3.1 s
datastore gc, datastore compact, model delete, workflow delete under 2 s under 2 s

Expected. As #3759's Decision 1 planned for this case: data prune alone streams its status lines live in log mode, and holds only its result until the commit. --json is unchanged. The other commands stay as they are, since they're under the 5 s bar.

3. A lagging checkout's read hangs about 112 s when Litestream's listing is cut

What happens. Found in swamp-club#3802's live checks. A checkout that's behind runs workflow history search while the bucket drops the replica listing request (_litestream LIST). The command hangs about 112 s, then exits 0. The released binary does the same, at 122 s. Every other outage outcome now exits within 8.3 s (#3802, #3882).

Repro. #3802's live-check harness (~/dogfood-3756, catch-up trigger scripts): a checkout behind the writer, with a cut proxy dropping only _litestream LIST requests during its catch-up.

Expected. The read finishes, or fails, within 15 s, like the other outage outcomes:

  • either it fails with datastore_v3_catch_up_unreachable (exit 75; the next command finishes the catch-up);
  • or, if a reader may proceed on its local copy, it says on stderr that the results may be out of date.

Pick one, and say why in the PR. It must never return silently after a long wait. Find what retries for 112 s (the Litestream restore, swamp's own retry, or the SDK) and bound it with the request deadline #3802 uses.

Done when

  • Crash recovery: profiled. On the dogfood's populated checkout it's either much faster (give the before and after) or prints progress, with no silent wait over about 5 s.
  • data prune: prints its status lines live in log mode, with its result after the commit. --json is unchanged.
  • The read during a listing cut: finishes or fails within 15 s on S3 and GCS, with a stable code or a stale-results warning.
  • Tests fail on main first where they can: a fake recovery with a counter, the prune output order, a hung listing through the fault seams.
  • The swamp-uat datastore suites pass unchanged.

Severity: medium. Nothing is lost, but each looks like a hang. Blocks closing Phase 4 of swamp-club#2865.

Blocked by: nothing.

02Bog Flow
✓OPEN✓TRIAGED✓IN PROGRESS✓SHIPPED+ 1 MOREASSIGNED+ 5 MOREREVIEW+ 9 MOREPR_LINKED+ 2 MORESESSION_SUMMARIZED

Shipped

10/25/2026, 1:07:45 AM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack7210/24/2026, 10:59:24 PM

Sign in to post a ripple.