Commit 6707794
authored
fix(cache): prevent unbounded TTLCache memory exhaustion and runtime instability (JhaSourav07#548)
## Description
Fixes JhaSourav07#537
This PR implements a bounded-capacity eviction strategy for the global
`TTLCache` instances used inside `lib/github.ts`.
Previously, the cache relied only on TTL expiration and did not enforce
any maximum capacity limits. Under sustained unique-user traffic
(crawler indexing, bots, traffic spikes, or large username scans), the
internal `Map` continuously retained strong references for new cache
entries, causing unbounded heap growth and increasing the risk of
Node.js/Vercel runtime instability or OOM crashes.
This fix introduces explicit cache ceilings while preserving the
existing TTL lifecycle and maintaining full backward compatibility.
### Changes Implemented
- Added bounded cache size limits for:
- `contributionsCache`
- `profileCache`
- `reposCache`
- Added production-focused defensive comments explaining:
- memory exhaustion risks
- crawler amplification scenarios
- runtime stability concerns
- bounded eviction rationale
### Root Cause
The cache instances were initialized without supplying `maxSize`:
const contributionsCache = new TTLCache<ContributionCalendar>();
const profileCache = new TTLCache<GitHubUserProfile>();
const reposCache = new TTLCache<GitHubRepo[]>();
Because the internal `Map` retained strong references to active entries:
- memory scaled linearly with unique usernames
- garbage collection could not reclaim active objects
- long-lived processes accumulated memory continuously
### Validation
Successfully verified with:
- `npm run test`
- `npm run lint`
- `npm run build`
### Test Results
- 22/22 test suites passed
- 275/275 tests passed
- Production build compiled successfully
### Runtime Validation
Stress-tested with 50,000 unique usernames.
| Metric | Result |
|---|---|
| Heap Before | 7.41 MB |
| Heap After | 15.55 MB |
| Behavior Before Fix | Unbounded growth |
| Behavior After Fix | Stable bounded plateau |
### Impact
This PR prevents:
- unbounded heap growth
- excessive GC pressure
- potential Vercel OOM crashes
- runtime instability under crawler/bot traffic
while preserving:
- existing TTL behavior
- cache semantics
- API compatibility
- backward compatibility
---
## Pillar
- [ ] 🎨 Pillar 1 — New Theme Design
- [ ] 📐 Pillar 2 — Geometric SVG Improvement
- [ ] 🕐 Pillar 3 — Timezone Logic Optimization
- [x] 🛠️ Other (Bug fix, refactoring, docs)
---
## Visual Preview
N/A — backend runtime stability fix
---
## Checklist before requesting a review:
- [x] I have read the `CONTRIBUTING.md` file.
- [x] I have tested these changes locally
(`localhost:3000/api/streak?user=YOUR_USERNAME`).
- [x] I have run `npm run format` and `npm run lint` locally and
resolved all errors.
- [x] My commits follow the Conventional Commits format.
- [x] I have started the repo.
- [x] I have made sure that I have only one commit in this PR.
- [x] All tests and production builds pass successfully.1 file changed
Lines changed: 14 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
114 | 114 | | |
115 | 115 | | |
116 | 116 | | |
117 | | - | |
118 | | - | |
119 | | - | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
120 | 131 | | |
121 | 132 | | |
122 | 133 | | |
| |||
0 commit comments