Load test for /prices at 5k rps (k6)#71
Open
githoboman wants to merge 2 commits into
Open
Conversation
…ntion and query API
…tHub Actions integration
|
@githoboman Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Here's what I built and why.
Closes #62
Files
tests/load/prices.k6.js (new) — the k6 load test
constant-arrival-rate executor — drives load in requests/sec (open model), so it actually holds the target RPS regardless of how fast the server responds. A closed VU model would silently drop below 5k RPS if latency rose, masking failures.
Threshold http_req_duration: ['p(95)<80'] — the acceptance criterion, enforced by k6's exit code (non-zero on breach → CI fails).
Also fails on errors / http_req_failed rate ≥ 1%, so a flood of 429s/401s can't masquerade as a passing fast run.
Fully env-configurable: BASE_URL, RATE (default 5000), DURATION (default 1m), API_KEY, PAIRS (default XLM/USDC, the docker-compose watched pair — findPair normalizes native→XLM).
.github/workflows/load.yml (new) — scheduled CI run
Daily at 04:00 UTC (off-peak) + manual workflow_dispatch with rate/duration inputs.
Spins up postgres + redis service containers, builds, applies schema, boots the server, warms the price cache (so the run measures the production hot path bots hit, not a cold miss), then runs k6 via the official Grafana actions.
src/index.ts (edited) — made the rate-limiter's IP fallback configurable via RATE_LIMIT_IP_MAX (default unchanged at 100). Required because a 5k-RPS flood from one IP would otherwise hit the hardcoded 100/min cap and 429 everything — the test would measure the limiter, not the endpoint. The workflow sets it high and runs with REQUIRE_API_KEY=false to isolate endpoint latency.
Verification
node --check on the k6 script: passes.
tsc --noEmit: my edit adds no new errors. The two webhookDispatcher.ts errors are pre-existing (confirmed by stashing my changes — they're on the clean a9923d5 baseline), so the existing CI is already red on them; that's out of scope here but worth flagging.