Every uptime monitor answers one question on a schedule, and the question is set by its type. An HTTP monitor asks "did this URL respond the way I expect?" A TCP monitor asks "is anything listening on this port?" A heartbeat monitor asks "has my job called in lately?" They sound interchangeable and they aren't. Point an HTTP monitor at a database port and it will never be green. Point a TCP monitor at a web server and it will be green while every visitor sees a 502. Put a heartbeat on a service that never calls it and it will alert once and then be ignored forever.
This guide explains what each type proves, what it can't see, and which one to reach for given the thing you're trying to watch. It ends with the combinations that work for common setups and the mismatches that make monitors lie.
HTTP monitors: judge the response
An HTTP monitor fetches a URL every check (every 3 minutes on the free plan, every minute on paid plans) and compares what came back to what you expect. At its simplest that's a status code: 200 means up, anything else means down. You can set the method (GET, HEAD, POST, and the rest), add custom headers such as an Authorization token, choose the expected status (a login page that correctly returns 401 to an anonymous request is a fine liveness signal), and set a timeout that doubles as your definition of "too slow." Every HTTPS monitor also tracks the certificate's expiry for free.
Three modes extend what an HTTP monitor can see, all on Pro and above. Keyword monitoring requires (or forbids) a string or regular expression in the response body, which catches the server that returns 200 with an error page, a captive portal, or a blank template. Content-change detection hashes the body and alerts when it changes, for pages that should be static. Content-staleness alerts when a page hasn't changed in N days, for feeds and dashboards that should be updating. Each monitor has one assertion; if you need "contains X" and "doesn't contain Y," that's two monitors.
What it proves: the whole path from the internet to your application worked and the application answered acceptably. This is the closest a monitor gets to a user's experience, which is why it's the default. What it can't see: anything without a URL, anything on a bare IP address (CronAlert's checks run on Cloudflare's network, which won't make HTTP requests to a bare IP), anything behind a self-signed certificate, and anything behind NAT or a VPN. It also doesn't send a request body, so a POST-only endpoint that needs a payload is better covered by a GET health endpoint next to it.
TCP port monitors: judge the handshake
A TCP monitor attempts to open a connection to a host and port and records whether the handshake completed within the timeout. Accepted means up. Refused, no route, or timeout means down. It never sends application data: it doesn't log in to SSH, doesn't run a query on Postgres, doesn't speak Minecraft's protocol. That's the point. It works for every protocol because it ignores all of them.
What it proves: a service is listening on that port and reachable from the internet. It also works where HTTP can't: a server known only by IP, a port serving a self-signed certificate, SSH, databases, IMAP and SMTP submission, RDP, game servers. What it can't see: whether the service behind the port works. A database that accepts connections and rejects every query, a web server returning 502s, a deadlocked process holding its socket open all pass a TCP check. There's also no ICMP ping; a TCP check on port 22 is the equivalent for a Linux host and proves strictly more. UDP services (DNS on 53, WireGuard, most game servers besides Java Minecraft) can't be reached by a TCP handshake at all. TCP monitors are on the Pro plan and above.
Heartbeat monitors: judge the silence
A heartbeat monitor makes no request. It gives you a unique URL, and your job requests that URL when it finishes successfully. You tell CronAlert how often to expect the ping, and it alerts when the deadline passes with no ping: expected interval plus a grace period, where the default grace is one interval capped at an hour, so a 1-minute heartbeat alerts after 2 minutes and a nightly one after 25 hours. The next ping resolves the incident.
What it proves: the job ran, finished, and reached the point where it pings, which, if you ping only on verified success, means the job worked. It's the only type that can see scheduled work, and the only type that can see anything an external check can't reach: a machine behind NAT, a service on a VPN, a device on a cellular connection. A script inside such a host checks whatever it likes (disk, services, a mounted share, a backup's age) and pings only when all of it passes, so a dozen internal conditions ride on one outbound request. What it can't see: anything the script doesn't check, and it can't tell you a job failed faster than the deadline; a job that dies at 2:05 AM with a 25-hour deadline is reported at 3 AM the next day, which is why the grace period matters. Heartbeats are on the Pro plan and above.
The decision table
| You want to watch | Use | Why |
|---|---|---|
| A website or landing page | HTTP | Status code plus a keyword that only appears when the page rendered. HTTPS tracks the certificate for free. |
| A REST API or health endpoint | HTTP | GET with any auth header you need; expected status 200. Keyword "ok":true on Pro catches degraded dependencies. |
| A POST-only or GraphQL endpoint | HTTP on a GET health route, or a GET query | Monitors don't send bodies. Many GraphQL servers accept GET /graphql?query=…; otherwise expose a GET health field. See GraphQL monitoring. |
| A server by IP, SSH, RDP | TCP | HTTP can't reach bare IPs; port 22 or 3389 proves the box is up and the service is listening. |
| A database, Redis, or message broker port | TCP, only if deliberately exposed | Otherwise, an HTTP health endpoint on the app that uses it tells you more and exposes less. |
| Mail (IMAP, SMTP submission) | TCP on 993 / 587 / 465 | Port 25 can't be checked from Cloudflare's network. See mail monitoring. |
| A game server | TCP (Java Minecraft) or heartbeat (UDP games) | Plus a heartbeat for the "running but frozen" case. See game servers. |
| An admin UI with a self-signed certificate (Proxmox, NAS, router) | TCP on its port, or nothing from outside | HTTPS checks fail the handshake. Better: don't expose it; use a heartbeat from inside. See Proxmox and NAS. |
| A cron job, backup, scheduled task, or ETL | Heartbeat | Ping on verified success at the end of the job; expected interval = the schedule. See backups. |
| A queue worker or long-running process | Heartbeat | Ping each loop or each N minutes from inside the process. See background workers. |
| Anything behind NAT, a VPN, or a firewall | Heartbeat | A script inside checks it locally and pings outward. See VPNs, Home Assistant, IoT devices. |
| A UDP service (DNS resolver, WireGuard) | Heartbeat | No TCP handshake to test. A script on the host queries it locally. See Pi-hole and AdGuard Home. |
| A whole server | All three | TCP on 22, HTTP per site, heartbeat from a health script. See monitoring a VPS. |
Combining types, and reading the disagreement
The strongest setups use two or three types on the same system, not because more monitors are better but because they fail differently. A server with a TCP check on SSH, an HTTP check on each site, and a heartbeat from a script inside produces a readable pattern in every outage:
- TCP down, HTTP down, heartbeat silent: the host is gone. Power, kernel, provider.
- TCP up, HTTP down, heartbeat fine: the application or the reverse proxy. The box is healthy.
- TCP up, HTTP up, heartbeat silent: degraded inside. Disk, memory, a stopped service, a stale backup. The script's log says which.
- TCP up, one HTTP down: that one service.
Three monitors cost you nothing extra in attention when things are fine and save you the first fifteen minutes of every incident. The how many monitors guide works through what that means for a typical account.
Five mismatches that make a monitor lie
- HTTP on a bare IP. It can't be created; CronAlert rejects the URL because Cloudflare would return a synthetic 403 without contacting your server. Use TCP, or give the host a DNS name.
- HTTPS on a self-signed certificate. Permanently down with a certificate error while the service is fine. Use TCP on the port, a real certificate, or plain HTTP where appropriate.
- TCP as a health check. Green through a 502, a full disk, a database in recovery. Reachability only; pair it with HTTP or a heartbeat.
- Heartbeat pinged at the start of the job, or unconditionally. A job that starts and crashes, or a script whose checks fail but pings anyway, looks healthy forever. Ping at the end, after verifying success, and only then.
- Heartbeat interval set to the job's duration instead of its schedule. A nightly job that takes 40 minutes expects a ping every 24 hours, not every 40 minutes. The grace period is where run-time variance goes.
Frequently asked questions
What's the difference between the three types?
HTTP judges a URL's response. TCP judges whether a port accepted a connection. Heartbeat judges whether your job called in on time.
When is TCP better than HTTP?
Non-HTTP services, bare IPs, and self-signed certificates. It proves listening, not health, so pair it with something that does.
Can a monitor have two types?
No, but a system should have several monitors of different types. Their disagreement is the diagnosis.
Which types are free?
HTTP and HTTPS, with SSL tracking and custom headers. TCP, heartbeats, keyword and content modes are Pro ($5/mo). Multi-region is Team and above.
Does an HTTP monitor send a request body?
No. Methods and headers, yes; bodies, no. Use a GET health route for POST-only endpoints.
Match the question to the thing
Pick the type by asking what you actually need to know. If it's "do users get a good response," HTTP. If it's "is something listening," TCP. If it's "did the job run" or "is the thing I can't reach from outside okay," heartbeat. Then add the second type that would tell you why the first one went red. Create a free account, start with HTTP monitors on what you serve, and add the rest as you go. Related reading: setting up monitoring in 5 minutes, what uptime monitoring is, how often to check, and avoiding false positives.