Six months ago I was manually refreshing my client's website after every deployment, praying it stayed up.
That's when I decided to build WhistleBlower — a real-time uptime monitoring tool with alerts, status pages, and incident tracking.
Here's what I built and what I learned.
What WhistleBlower does
- 🔴 HTTP, TCP, PING, and DNS monitoring — not just websites
- 📧 Instant alerts via email, Slack, Discord, and SMS
- 📊 Public status pages — your users always know what's up
- 💓 Heartbeat monitoring — know when your cron jobs die silently
- 🔒 SSL certificate expiry alerts — never get caught with an expired cert
- 👥 Team & on-call scheduling for agencies
The tech stack
- Frontend: Next.js 14 + Tailwind CSS
- Backend: Node.js + Express + TypeScript
- Database: MySQL (Railway)
- Emails: Resend
- Payments: Razorpay
- Deploy: Vercel (frontend) + Railway (backend)
- Cron worker: GitHub Actions (free!)
The hardest part
ICMP ping is blocked on containerized environments like Railway and Docker. My PING monitors were silently failing in production while working fine locally.
The fix? A 3-strategy fallback:
- ICMP ping (works on bare metal / GitHub Actions)
- TCP connect to port 443, then 80
- DNS lookup as final fallback
async function checkPing(host: string): Promise<CheckResult> {
// Strategy 1: ICMP
const icmpResult = await tryICMP(host);
if (icmpResult.isUp) return icmpResult;
// Strategy 2: TCP fallback (containers block ICMP)
for (const port of [443, 80]) {
const tcp = await tryTCP(host, port);
if (tcp.isUp) return tcp;
}
// Strategy 3: DNS
return tryDNS(host);
}
What I'd do differently
- Start with a free tier plan from day one — I almost didn't add one
- Deploy earlier — I spent too long perfecting locally
- GitHub Actions as a cron runner is genuinely brilliant for side projects
Try it free
👉 whistle-blower-two.vercel.app
Free plan includes 5 monitors, 5-minute checks, email alerts — no credit card needed.
Would love your feedback in the comments! 🚀
Top comments (2)
The heartbeat monitoring line is the one that earns this, "know when your cron jobs die silently" is the failure mode every other uptime tool misses, because a cron that stops running throws no error, returns no 500, just quietly stops happening, and your dashboard stays green while the work silently stops. Monitoring presence-of-success instead of absence-of-error is a genuinely different mental model and most teams learn it the hard way when a backup job was dead for three weeks. Building the whole thing (HTTP/TCP/PING/DNS, status pages, on-call) in 30 days is the right scope discipline too, you shipped the full loop instead of polishing one check forever. The honest question on a 30-day SaaS: how much of that month was the actual monitoring logic versus the surrounding plumbing, alert fan-out to four channels, status pages, team scheduling, auth, billing? That ratio (interesting core vs boring wiring) is the exact thing I'm attacking with Moonshift, having agents own the plumbing so the 30 days goes to the part that's your product. What ate the most time?
Thanks! You described the heartbeat problem perfectly.
Honest answer: building the actual monitoring (checking if sites are up/down) took only 20% of my time. The other 80% was boring stuff — login system, email alerts, Slack notifications, billing, admin panel. All necessary but not interesting.
The trickiest part was making sure when a site goes DOWN, you only get ONE alert email - not one every 5 minutes. That small logic took more debugging than I expected.Moonshift sounds really interesting. My question for you — when an AI agent writes the code, how easy is it for a developer to go in and change something? That handoff between agent and human is the hard part I'd want to see solved