UptimeMonitoring.com
Menu
← Blog

Don't Trust a Green Deploy: Add a Real Health Gate to Your CI

By Lucian, founder of Monitive

Here is a failure mode that has bitten me more than once. CI goes green. The deploy step says success. Slack gets the little checkmark. And the site is down anyway.

It happens because “the deploy script exited 0” and “users can actually reach the service” are two different claims, and most pipelines only check the first one. The container started, sure. But DNS had not propagated, or the load balancer was still draining the old pods, or a config value was missing and every request returns 500 the moment real traffic hits the public URL. Your CI never tried the public URL. It trusted the exit code.

The fix is a health gate: a step that runs after deploy and fails the pipeline unless the service is genuinely healthy when checked from the outside, the same path your users take. If it is down, the build goes red and you find out in 90 seconds, not when a customer emails you.

Here is how to add one.

The 5-line version (GitHub Actions)

If you already have a monitor on the URL, gate the deploy on it:

- run: ./deploy.sh
- name: Verify deploy health
uses: uptimemonitoring/assert-healthy@v1
with:
api-key: ${{ secrets.UPTIMEMONITORING_API_KEY }}
monitor-id: ${{ vars.MONITOR_ID }}
timeout: 120

That step polls the monitor and fails if it does not report healthy within the timeout window. Deploy, then prove the service is serving traffic before the job is allowed to pass. The step also exposes healthy, last-status, last-region, and last-ttfb-ms as outputs, so you can branch on them or print them into the run log.

Don’t have a monitor yet? Creating one is a single API call (or one sentence to Claude, more on that below), and the free tier covers 50 of them with a GitHub login and no email.

The matrix version (gate several services at once)

Shipping a few services in one pipeline? Fan the check out:

jobs:
assert-healthy:
runs-on: ubuntu-latest
strategy:
matrix:
monitor: [1287, 1288, 1289]
steps:
- uses: uptimemonitoring/assert-healthy@v1
with:
api-key: ${{ secrets.UPTIMEMONITORING_API_KEY }}
monitor-id: ${{ matrix.monitor }}

One red service fails the gate. You do not mark the release done until all of them are actually up.

Not on GitHub? Gate it from your AI agent

If your deploy runs through Claude, Cursor, or any MCP-aware tool, the same check is one instruction. UptimeMonitoring ships an MCP server with an assert_monitor_healthy tool that succeeds only when the monitor is currently up:

Add UptimeMonitoring as an MCP server
Deploy the app
Assert that the production monitor is healthy, and stop if it isn't

The agent runs your deploy, then calls assert_monitor_healthy. If the service is down, the assertion fails and the agent stops instead of cheerfully reporting “deployed!” on top of an outage. Same gate, no YAML.

Why check from the outside, not from inside the cluster

A lot of teams already have a /healthz endpoint and a readiness probe, and that is good, but it answers a narrower question: “is this pod alive?” It does not test DNS, TLS, the CDN, the load balancer, or the actual public hostname. Those are exactly the layers that break a deploy while every pod reports healthy.

An external monitor checks the URL your users hit, through the whole stack, from outside your network. That is the claim you actually care about: not “the process is running” but “a request from the internet gets a good response.” A post-deploy gate built on that is testing reality, not a proxy for it.

When you don’t need this

To be fair: if you deploy by pushing to a managed platform that already blocks promotion on its own external health checks, you may have this covered. And if a few minutes of “deployed but unreachable” genuinely does not matter for what you are shipping, skipping the gate is a reasonable call. This is for the case where a silently broken deploy costs you, and you would rather the pipeline catch it than your users.

Start free

If you want to add a health gate today: sign up with your GitHub login (no email, no billing details), create a monitor on your production URL, and drop the five-line step into your pipeline. Fifty monitors free.

Get your API key and gate your next deploy.

Prefer to run everything from your editor? Here’s how to monitor uptime from Claude in plain English.