Refactor event-log eviction to an O(1) ring buffer
Description
recordEvent in src/index.ts appends to the eventLog array and, once it exceeds EVENT_LOG_CAP (10,000), calls eventLog.shift() to drop the oldest entry. Array.prototype.shift() is O(n) because it reindexes every remaining element, so once the log is full, every single write endpoint (POST /usage, POST /usage/bulk, POST /settle, webhook test) pays an O(n) cost per event — on a hot ingestion path. This issue replaces the array-shift eviction with an O(1) ring buffer while preserving all read semantics.
Requirements and context
- Repository scope: Agentpay-Org/Agentpay-backend only.
- Replace the
push/shift eviction with a fixed-capacity ring buffer (or head-index window) so insertion and eviction are O(1).
- Preserve the exact read behaviour of
GET /api/v1/events (chronological order, ?since/?type/?limit, last-N slice) and GET /api/v1/events/summary (counts + total).
- Keep
total semantics consistent (currently eventLog.length, capped at EVENT_LOG_CAP).
- Consider honouring the runtime
config.eventLogCap value (currently the constant EVENT_LOG_CAP is used while config advertises eventLogCap), and document the resolution.
Suggested execution
- Fork the repo and create a branch
git checkout -b refactor/performance-47-eventlog-ring-buffer
- Implement changes
- Write code in: the
eventLog/recordEvent definitions and the two events read handlers in src/index.ts (or a small src/eventLog.ts).
- Write comprehensive tests in: new
src/eventlog-ring.test.ts — order preserved across wraparound, eviction keeps newest, summary counts correct after wrap, ?since/?type/?limit parity with the old behaviour.
- Add documentation: note the ring-buffer design and
eventLogCap resolution in docs/events.md if present, else in code comments.
- Add TSDoc on the ring-buffer helpers.
- Validate security assumptions: eviction cannot leak or duplicate entries; ordering is deterministic.
- Test and commit
Test and commit
- Run
npm run build, npm test, and npm run lint.
- Cover edge cases: below cap, exactly at cap, wraparound past cap, summary after wrap, last-N slice after wrap.
- Include the full
npm test output and a brief before/after complexity note in the PR description.
Example commit message
perf: replace o(n) event-log shift with an o(1) ring buffer
Guidelines
- Minimum 95 percent test coverage for impacted modules.
- Clear, reviewer-focused documentation.
- Timeframe: 96 hours.
Community & contribution rewards
- 💬 Join the AgentPay community on Discord for questions, reviews, and faster merges: https://discord.gg/eXvRKkgcv
- ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project — if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward.
Refactor event-log eviction to an O(1) ring buffer
Description
recordEventinsrc/index.tsappends to theeventLogarray and, once it exceedsEVENT_LOG_CAP(10,000), callseventLog.shift()to drop the oldest entry.Array.prototype.shift()is O(n) because it reindexes every remaining element, so once the log is full, every single write endpoint (POST /usage,POST /usage/bulk,POST /settle, webhook test) pays an O(n) cost per event — on a hot ingestion path. This issue replaces the array-shift eviction with an O(1) ring buffer while preserving all read semantics.Requirements and context
push/shifteviction with a fixed-capacity ring buffer (or head-index window) so insertion and eviction are O(1).GET /api/v1/events(chronological order,?since/?type/?limit, last-Nslice) andGET /api/v1/events/summary(counts+total).totalsemantics consistent (currentlyeventLog.length, capped atEVENT_LOG_CAP).config.eventLogCapvalue (currently the constantEVENT_LOG_CAPis used while config advertiseseventLogCap), and document the resolution.Suggested execution
git checkout -b refactor/performance-47-eventlog-ring-buffereventLog/recordEventdefinitions and the two events read handlers insrc/index.ts(or a smallsrc/eventLog.ts).src/eventlog-ring.test.ts— order preserved across wraparound, eviction keeps newest,summarycounts correct after wrap,?since/?type/?limitparity with the old behaviour.eventLogCapresolution indocs/events.mdif present, else in code comments.Test and commit
npm run build,npm test, andnpm run lint.npm testoutput and a brief before/after complexity note in the PR description.Example commit message
perf: replace o(n) event-log shift with an o(1) ring bufferGuidelines
Community & contribution rewards