Skip to content

fix(admin): use cursor-based pagination for API request log download#2259

Merged
chrarnoldus merged 8 commits intomainfrom
fix/api-request-log-download-memory
Apr 13, 2026
Merged

fix(admin): use cursor-based pagination for API request log download#2259
chrarnoldus merged 8 commits intomainfrom
fix/api-request-log-download-memory

Conversation

@kilo-code-bot
Copy link
Copy Markdown
Contributor

@kilo-code-bot kilo-code-bot bot commented Apr 9, 2026

Summary

The /admin/api/api-request-log/download endpoint loaded all matching rows into memory before archiving them into a ZIP. For users with many API requests, this caused Vercel to kill the instance with an OOM error (Vercel Runtime Error: instance was killed because it ran out of available memory).

  • Replaced the single unbounded query with cursor-based pagination (batches of 100 rows), so only one batch is in memory at a time.
  • Added backpressure awareness: after each batch, the code waits for the PassThrough stream to drain before fetching the next batch, preventing archiver from buffering unbounded data.
  • Used a lightweight COUNT(*) query to preserve the existing 404 behavior when no records match.

Verification

  • pnpm typecheck — passes with no errors
  • pnpm lint — passes (via pre-push hook)
  • pnpm format:check — passes (via pre-push hook)

Visual Changes

N/A

Reviewer Notes

  • The BATCH_SIZE of 100 is conservative. Each row's request (jsonb) and response (text) columns can be large, so keeping batches small limits peak memory. This can be tuned up if the count query + extra round-trips become a bottleneck.
  • Ordering changed from created_at to id for cursor pagination correctness (timestamps can have duplicates; id is a monotonically increasing bigserial).

The download endpoint loaded all rows into memory at once, causing
Vercel OOM kills for users with many API requests. Switch to
cursor-based pagination (batches of 100) with backpressure-aware
stream draining so only one batch is in memory at a time.
Comment thread apps/web/src/app/admin/api/api-request-log/download/route.ts Outdated
@kilo-code-bot
Copy link
Copy Markdown
Contributor Author

kilo-code-bot bot commented Apr 9, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (1 files)
  • apps/web/src/app/admin/api/api-request-log/download/route.ts

Reviewed by gpt-5.4-20260305 · 311,613 tokens

kilo-code-bot bot and others added 7 commits April 9, 2026 17:48
Address review comment: if a batch query or archive.finalize() fails,
destroy the passthrough stream so the error surfaces to the client
instead of hanging until timeout.
Adds an optional 'model' query parameter to filter the download by a
specific model. When not set, all models are included (existing behavior).
Replace / and : in the model name so the ZIP filename is safe for
all filesystems.
@chrarnoldus chrarnoldus merged commit 2b8ca34 into main Apr 13, 2026
14 checks passed
@chrarnoldus chrarnoldus deleted the fix/api-request-log-download-memory branch April 13, 2026 08:04
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.

2 participants