PulseGuard is a self-hosted uptime monitoring tool that keeps your free-tier services alive (Render, Railway, etc.) by pinging them on a schedule. It features a beautiful dark-mode dashboard showing real-time status, response times, and uptime history.
βββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββ
β GitHub Actions ββββββΆβ Vercel (Next.js) ββββββΆβ Supabase β
β (Scheduler) β β (Dashboard+API) β β (Postgres) β
β every 5 min β β β β β
βββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββ
β β²
β GET /api/ping-targets β
β POST /api/ping-callback
ββββββββββββββββββββββββββ
All free tier: Vercel (Hobby), Supabase (Free), GitHub Actions (Free for public repos, 2000 min/mo for private).
- π’ Real-time status monitoring β See at a glance which services are up or down
- π Response time charts β Track performance over 24h, 7d, or 30d
- π Uptime percentages β Know your service reliability
- βΈοΈ Pause/Resume β Toggle monitoring without losing history
- π Simple auth β Password-protected dashboard
- π€ GitHub Actions scheduler β Reliable 5-minute ping intervals
- π Beautiful dark UI β Modern, card-based dashboard
- Go to supabase.com and create a new project
- Go to SQL Editor and run the migration in
supabase/schema.sql - Go to Settings β API and copy:
- Project URL β
NEXT_PUBLIC_SUPABASE_URL - anon public key β
NEXT_PUBLIC_SUPABASE_ANON_KEY - service_role secret key β
SUPABASE_SERVICE_ROLE_KEY
- Project URL β
-
Push this repo to GitHub
-
Go to vercel.com and import the repo
-
Add the following Environment Variables in Vercel project settings:
Variable Value NEXT_PUBLIC_SUPABASE_URLYour Supabase project URL NEXT_PUBLIC_SUPABASE_ANON_KEYYour Supabase anon key SUPABASE_SERVICE_ROLE_KEYYour Supabase service role key APP_PASSWORDYour chosen dashboard password PING_CALLBACK_SECRETA random secret (generate with openssl rand -hex 32) -
Deploy!
-
In your GitHub repo, go to Settings β Secrets and variables β Actions
-
Add these Repository Secrets:
Secret Value VERCEL_APP_URLYour Vercel deployment URL (e.g., https://pulseguard.vercel.app)PING_CALLBACK_SECRETSame secret you set in Vercel -
The workflow at
.github/workflows/ping.ymlwill automatically run every 5 minutes
- Log in to your dashboard at
https://your-app.vercel.app - Add a URL to monitor (e.g., your Render service)
- Go to GitHub β Actions tab β Uptime Pinger β Run workflow (manual trigger)
- Wait ~30 seconds, then refresh your dashboard β you should see the ping result!
| Variable | Where | Description |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Vercel | Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Vercel | Supabase anon/public key |
SUPABASE_SERVICE_ROLE_KEY |
Vercel | Supabase service role key (server-side only) |
APP_PASSWORD |
Vercel | Password for dashboard login |
PING_CALLBACK_SECRET |
Vercel + GitHub | Shared secret for ping callbacks |
VERCEL_APP_URL |
GitHub | Your Vercel deployment URL |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/urls |
Session | List all monitored URLs with status |
POST |
/api/urls |
Session | Add a new URL |
PATCH |
/api/urls/:id |
Session | Update URL or toggle active |
DELETE |
/api/urls/:id |
Session | Delete URL and its history |
GET |
/api/urls/:id/history |
Session | Get ping history (24h/7d/30d) |
GET |
/api/ping-targets |
Public | Get active URLs (for GitHub Action) |
POST |
/api/ping-callback |
Bearer Token | Report ping results (for GitHub Action) |
- Frontend: Next.js 14+ (App Router), TypeScript, Tailwind CSS
- Charts: Recharts
- Database: Supabase (PostgreSQL)
- Scheduler: GitHub Actions
- Hosting: Vercel
# Install dependencies
npm install
# Copy env file and fill in values
cp .env.example .env.local
# Run dev server
npm run devMIT