How Doyouok Monitors Uptime and Heartbeats: Our Tech Stack and OCI Load Balancer Setup
Doyouok is a lightweight uptime and heartbeat monitoring service: point a scheduled job, a nightly backup script, or a public website at us, and we tell you the moment it stops checking in. This post walks through what we built, the stack behind it, and how the service is deployed on Oracle Cloud Infrastructure (OCI) — including the Network Load Balancer (NLB) setup in front of our web tier.
What Doyouok actually watches
Two monitoring modes cover most of what teams need:
- Life Monitor (heartbeat/dead man's switch): your cron job, backup, or worker pings a unique URL on a schedule. If the ping doesn't arrive within the configured timeout window, we mark the check
Downand notify you. - Task Monitor: for jobs that log a start/end and a duration (e.g. "did last night's backup finish, and how long did it take?"), we track a rolling history so regressions in run time are visible before they become outages.
Both modes share the same dashboard: current status, last check-in, last-down history, and a small per-check activity chart so you can spot flaky jobs at a glance.
Tech stack
Doyouok is intentionally boring on the technology side — boring is reliable:
- Backend: ASP.NET Core MVC (C#) on .NET, with EF Core against PostgreSQL for storage.
- Frontend: server-rendered Razor views with Bootstrap — no SPA build step, no client-side state to keep in sync with the server.
- Background work: a hosted worker service scans for overdue checks and dispatches notifications (email, and other channels) outside the request path.
- Content: this blog itself is authored in Markdown and rendered server-side, which is what prompted this post.
Keeping the stack small means fewer moving parts between "a check stopped pinging" and "you get notified" — which matters a lot for a monitoring product specifically.
Deployment architecture on OCI
The web tier sits behind an OCI Network Load Balancer (NLB) with a backend set of 2 app servers. That lets us take one server out of rotation, upgrade it, and put it back before touching the other — the goal being zero downtime during app upgrades.
Why this matters for a monitoring product
There's a bit of "eat your own dog food" here: the same reliability properties we're selling — fast health checks, quick failover, no single point of failure — are the ones we rely on to keep Doyouok itself up. If our own NLB health checks or backend instances misbehave, we'd rather find out from our own infrastructure than from a customer's Slack alert.
If you're running scheduled jobs, backups, or services that fail silently, that's exactly the gap Doyouok is built to close — set up a check, get pinged when something stops pinging you.