Session Receipt
Project: streampilot-demo-app
Summary
Fixed the retry loop in the upload worker and locked in the backoff strategy.
Decisions made
2 recordedCap upload retries at five attempts.
Keeps failed jobs from cycling forever while still recovering from short outages — five attempts covers every transient failure we saw in the logs.
Saved to project memoryUse exponential backoff with jitter, capped at 30 seconds.
Spreads retry traffic so a recovering upload service isn’t hit by a synchronized burst from every waiting client at once.
Saved to project memoryWhat changed
4 files-
src/workers/upload-worker.ts L48–112
Replaced the unbounded retry loop with an explicit five-attempt limit.
-
src/lib/retry-policy.ts L1–67 new
Backoff policy in one place: exponential delay with randomized jitter, capped at 30 s.
-
tests/upload-worker.test.ts L22–146
Added coverage for temporary failures, five-attempt exhaustion, and jitter bounds.
-
docs/upload-reliability.md L14–38
Wrote down the agreed retry behavior so the next session starts from it.
Proof
full suite34 passed 0 failed
$ npx vitest run
PASS tests/upload-worker.test.ts
✓ retries temporary upload failures
✓ stops after five attempts
✓ applies bounded jitter
… 31 more passing tests
Tests 34 passed, 0 failed
Duration 4.2s
The full transcript stays in the ContextStream workspace — this shared receipt carries the proof above.
Lesson captured
1 savedUpload retries must always have a terminal condition — including when the upstream service returns an ambiguous timeout.
WarningThis lesson will auto-surface next time this code is touched.
Open items
carried to next session-
Add retry-attempt telemetry to the operations dashboard so exhaustion shows up before users report it.
-
Confirm production timeout thresholds with the infrastructure team.