Blog / Ping vs HTTP Checks — What "Up" Actually Means
uptime monitoring http icmp

Ping vs HTTP Checks — What "Up" Actually Means

Ping succeeds while your site serves 500s; HTTP 200 while the page is broken. What ICMP, TCP, HTTP and browser checks each prove — and when to use them.
The CompleteStatus Team · · 6 min read
Ping vs HTTP Checks — What "Up" Actually Means
Want this checked continuously?
CompleteStatus grades your headers, SSL and email security 24/7 — free, commercial use allowed.
Monitor your site free

"Is the site up?" sounds like a yes/no question. It isn't — it's four or five different questions stacked on top of each other, and each kind of monitoring check answers a different one. A server can respond to ping while every page returns a 500. A web server can return 200 while the page it serves is a blank shell. Teams get burned not because their monitoring failed, but because it faithfully answered a question nobody meant to ask.

This post walks the stack layer by layer — ICMP ping, TCP connect, HTTP request, full browser render — and pins down exactly what each check proves, what it can't see, and which one your website actually needs.

ICMP ping: "the machine's network stack is alive"

ping sends an ICMP echo request; the target's kernel replies. That's the whole transaction. A successful ping proves:

  • The host is powered on and its network stack is functioning.
  • A route exists between the probe and the host.

And that's all. Ping doesn't touch your web server, your application, or your database — the kernel answers ICMP even if every process on the machine has crashed. The classic failure: nginx dies, the box pings beautifully, and your "monitoring" stays green for the entire outage.

Ping has real uses — it's the right tool for network gear, for distinguishing "host unreachable" from "service down" during diagnosis, and for infrastructure that speaks no higher protocol. Two caveats even there: many hosts and firewalls drop ICMP entirely (so ping "failure" can be policy, not outage), and ICMP is often deprioritized under load, making its latency numbers unreliable.

As a website check, though, ping answers the wrong question. Nobody visits your site over ICMP.

TCP connect: "something is listening on that port"

One layer up, a TCP check performs the three-way handshake against a specific port — connect() to port 443, success or failure. This proves everything ping proves, plus:

  • A process is listening on the port and accepting connections.

It still says nothing about whether that process is healthy. A wedged application server whose accept queue still works, a reverse proxy faithfully accepting connections in front of a dead backend, a deadlocked process that accepts and then hangs — all pass a TCP check while serving nothing.

TCP checks earn their place for non-HTTP services: SMTP, IMAP, database ports you intentionally expose, game servers, anything where "port accepts connections" is a meaningful proxy for service health. For a website, it's a stepping stone, not a destination.

HTTP request: "the application answered"

Now we're speaking the actual protocol of the web. An HTTP check requests a real URL and evaluates the response. This is the first layer where your application — not just your infrastructure — participates:

  • DNS resolved (the check had to look you up, like a real visitor).
  • TLS negotiated — an expired or invalid certificate fails the check, exactly as it blocks a browser.
  • The web server and application produced a response, with a status code, headers, and a body, in measurable time.

A 500 from a crashed app, a 502 from a dead backend, a certificate that expired at midnight, a DNS record someone fat-fingered — an HTTP check catches all of it, and each failure mode reports differently, which is half your diagnosis done before you've opened a terminal.

But there's a famous gap left: HTTP 200 doesn't mean the page works. The most embarrassing outages ship with a green status code — the CMS whose database is down rendering a styled "Error establishing a database connection" page with a 200, the single-page app serving its empty shell perfectly while the JavaScript inside is broken, the maintenance page someone forgot to remove. The server answered; the site is gone.

HTTP + keyword assertions: the sweet spot

The fix costs almost nothing: assert on the response body, not just the status code.

  • Positive assertion — the response must contain a string that only exists when the page rendered correctly: your footer copyright, a product heading, Add to cart. If the marker is missing, the page is broken regardless of what the status code claims.
  • Negative assertion — the response must not contain known failure text: Fatal error, Warning:, database connection. Error pages love to travel with a 200.

You can approximate this by hand — which also makes a nice mental model of what a good monitor does every minute:

curl -fsS https://example.com/ | grep -q "© Example Inc" \
  && echo "UP" || echo "DOWN or broken"

For websites, this combination — a real HTTP request plus one or two content assertions, with response time recorded — is the sweet spot on the cost/fidelity curve. It exercises DNS, TLS, the web server, the application, and (via the rendered content) usually the database too, in a check cheap enough to run every minute from multiple locations. One layer of honesty on top of "did it respond" eliminates the entire class of green-dashboard outages.

Full browser render: the deepest — and heaviest — check

The top of the stack is a real headless browser loading the page: executing JavaScript, fetching subresources, rendering. It's the only check that truly sees what a user sees, and it's the right tool for client-heavy apps where the server response is just an app shell, or for asserting that a third-party script didn't take your page down with it.

The trade-offs are weight and noise: browser checks are an order of magnitude slower and costlier, so they run less frequently — and they fail for more reasons, some of which (a slow third-party font, an ad script) may not be your outage. The pragmatic pattern is layered: HTTP-plus-keyword checks every minute as the primary alarm, a browser-level check on your most critical flow as the deep verification.

Match the check to the question

A quick decision table:

You want to know… Use
Is the host reachable at all? ICMP ping
Is a non-HTTP service accepting connections? TCP connect
Is my website actually serving working pages? HTTP + keyword assertions
Does my JS-heavy app render for real users? Browser check (plus HTTP as the fast layer)

The pattern to avoid is the mismatch — pinging a web server and calling it uptime monitoring. That check will spend years agreeing with you and then stay green through the one outage that mattered.

CompleteStatus is built around the sweet spot: HTTP checks with keyword and response-time assertions as the default for websites, plus TCP and ping checks for the infrastructure underneath, all in one dashboard with alerts that tell you which layer failed. It's the difference between "something's wrong" and "the cert expired" arriving in the same notification. Create a free account, point a check at your homepage, and add one keyword assertion — that single string is the cheapest insurance in monitoring.

Stop checking by hand

CompleteStatus runs these exact checks around the clock — uptime, SSL, DNS, security headers and SPF/DKIM/DMARC — and alerts you the moment something changes. One dashboard, one bill.
Start free Run a free check
Uptime is table stakes. We watch the rest — security headers, email authentication, certs and DNS, with the fix attached.
Start free
Company
© 2026 CompleteStatus. All rights reserved. CompleteStatus — operated in the United States · support@completestatus.com