fix: infrastructure cost optimizations across caching, polling, and batching#273
Closed
elzalem wants to merge 6 commits into
Closed
fix: infrastructure cost optimizations across caching, polling, and batching#273elzalem wants to merge 6 commits into
elzalem wants to merge 6 commits into
Conversation
Concurrent cache misses for the same key now share a single upstream fetch instead of each triggering redundant API calls. This eliminates duplicate work within Edge Function invocations under burst traffic. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Vessel positions do not change meaningfully in 10 seconds at sea. Reduces Railway relay requests by 66% with negligible UX impact. Stale threshold bumped to 45s to match the new interval. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Precise bounding box coordinates caused near-zero cache hit rate since every map pan/zoom produced a unique key. Snapping to a 1-degree grid lets nearby viewports share cache entries, dramatically reducing redundant OpenSky API calls. Co-Authored-By: Claude Opus 4.6 <[email protected]>
The loop awaited each ETF chart fetch individually, blocking on every Yahoo gate delay. Using Promise.allSettled lets all 10 fetches queue concurrently through the Yahoo gate, cutting wall time from ~12s to ~6s. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add getCachedJsonBatch() using the Upstash pipeline API to fetch multiple keys in a single HTTP call. Refactor aircraft details batch handler from 20 sequential GETs to 1 pipelined request. Co-Authored-By: Claude Opus 4.6 <[email protected]>
|
@elzalem is attempting to deploy a commit to the Elie Team on Vercel. A member of the Team first needs to authorize it. |
Owner
|
Thank you @elzalem Will review |
7 tasks
18 tests covering: cachedFetchJson request coalescing (in-flight dedup, cache-before-fetch ordering, cleanup), getCachedJsonBatch pipeline API, aircraft batch handler pipeline usage, bbox grid quantization (1-degree step, expanded fetch bbox), and ETF parallel fetch. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Owner
|
Merged under #284 |
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.
Summary
Five targeted optimizations to reduce infrastructure costs as the app scales. Each change is a separate atomic commit.
1. Request coalescing on cache misses
When multiple concurrent requests hit the same cache key during a miss, only the first triggers the upstream API call — the rest await the same in-flight promise. Eliminates duplicate work under burst traffic.
2. AIS maritime polling: 10s → 30s
Vessel positions do not change meaningfully in 10 seconds at sea. Stale threshold bumped to 45s to match.
3. Military flights bbox cache quantization
Previously, every map pan/zoom produced a unique bounding box → unique cache key → cache miss → fresh OpenSky API call. Now coordinates snap to a 1-degree grid (~111km), so nearby viewports share cache entries. Upstream fetch bbox is expanded to cover the full grid cell.
4. ETF flows: sequential → parallel fetch
The existing code wrapped each ETF fetch in a single-element
Promise.allSettledinside afor/awaitloop — effectively sequential. Now all 10 ETFs queue concurrently through the Yahoo rate-limit gate.5. Redis pipeline batch GET
Added
getCachedJsonBatch()using the Upstash pipeline API to fetch N keys in a single HTTP round-trip. Refactored the aircraft details batch handler from 20 sequential Redis GETs to 1 pipelined request.Estimated impact
At 500K monthly active users, assuming 1% have the maritime panel open at any given time (5,000 concurrent users):
Files changed (5 files, +109 / -22)
server/_shared/redis.ts—cachedFetchJson()coalescing +getCachedJsonBatch()pipelinesrc/services/maritime/index.ts— poll interval 10s → 30sserver/worldmonitor/military/v1/list-military-flights.ts— bbox grid quantizationserver/worldmonitor/market/v1/list-etf-flows.ts— parallel Promise.allSettledserver/worldmonitor/military/v1/get-aircraft-details-batch.ts— pipeline batch GETTest plan
🤖 Generated with Claude Code