Optimizing Next.js TV Dashboard Refresh to Preserve Neon Scale‑to‑Zero
TL;DR:
I bumped the TV dashboard auto‑refresh interval from 30 s to 15 min in src/features/tv/TVDashboard.tsx. This change frees up Neon compute resources and prevents unnecessary scaling events, keeping the database in a low‑cost state.
The Problem
Neon, our Postgres‑as‑a‑service provider, scales compute resources up and down automatically. With the TV dashboard polling the database every 30 seconds, the DB stayed “warm” all the time, consuming compute credits even when the data was static. The symptom was a spike in Neon compute usage and a higher bill, without any functional benefit.
ERROR: Neon compute headroom exceeded
- Frequent polling prevented scale‑to‑zero
What I Tried First
- Leave the 30 s interval unchanged – no improvement, compute still stayed active.
- Reduce to 5 min – still caused occasional scaling up because the refresh triggered a new connection each cycle.
- Add a debounce in the query layer – added complexity without addressing the root cause of the polling frequency.
The root issue remained: the UI kept re‑fetching data too often for a data source that changes only on manual sync.
The Implementation
1. Update the refresh constant
In src/features/tv/TVDashboard.tsx, the polling interval was originally set to 30 seconds:
// src/features/tv/TVDashboard.tsx
const REFRESH_MS = 30_000; // 30 s
I first bumped it to 5 minutes:
const REFRESH_MS = 300_000; // 5 min
But to give Neon more headroom, I then increased it further to 15 minutes:
const REFRESH_MS = 900_000; // 15 min
The final diff looks like this:
-const REFRESH_MS = 30_000;
+const REFRESH_MS = 900_000; // 15 min
2. Use the constant in the polling effect
The component uses useEffect with setInterval to re‑fetch TV data:
useEffect(() => {
const interval = setInterval(() => {
fetchTvData(); // async call to API/DB
}, REFRESH_MS);
return () => clearInterval(interval);
}, []);
With the new REFRESH_MS, the interval now triggers only every 15 minutes, drastically reducing the number of database connections.
3. Add documentation on the change
To keep the team informed, I added two markdown files in the repo root:
- CLAUDE.md – a high‑level incident recap and architecture overview.
- CLAUDE_CODE_CONTEXT.md – a snapshot of system status, including the updated refresh interval.
These docs help anyone reviewing the repo to understand why the change was made and its impact on Neon.
Key Takeaway
When polling a serverless database, set the refresh interval to the minimal frequency that still satisfies UX.
A 30 s interval can keep a database “warm” unnecessarily, while a 15 min interval can preserve compute headroom without hurting user experience. Always audit your polling logic against the database’s scaling model.
What's Next
- Move to server‑sent events – Replace polling with a WebSocket or SSE channel that pushes updates only when data changes, eliminating any idle queries.
-
Centralize refresh config – Store
REFRESH_MSin a.envfile so that it can be tuned per environment (dev, staging, prod). - Monitor Neon metrics – Add a small dashboard that visualizes compute usage over time to catch similar issues early.
vibecoding #buildinpublic #nextjs #react #neon #serverless #devops #typescript
Part of my Build in Public series — sharing the real process of building SaaS projects from Playa del Carmen, México.
Repo: zaerohell/pcview · 2026-08-03
#playadev #buildinpublic
Top comments (0)