Back to all posts
Proxy Pool Health Checks & Monitoring with Prometheus & Grafana

Proxy Pool Health Checks & Monitoring with Prometheus & Grafana

July 14, 2026

Introduction

When you rely on a proxy pool to keep your scraping, testing, or multi‑account workflows running, the last thing you want is an unexpected outage. Traditional proxy management often stops at a simple "does it work?" ping, leaving you blind to latency spikes, intermittent failures, or gradual degradation. By adding systematic health checks and visual monitoring, you can catch problems before they affect production, balance load across your pool, and keep automation pipelines humming.

This guide walks through a complete, production‑ready approach: defining what to measure, writing a health‑check script that reports metrics, exposing those metrics to Prometheus, and turning the data into actionable dashboards with Grafana. Along the way we’ll highlight best practices and show how a reliable proxy service like RoProxy makes the whole process smoother.

Why Traditional Proxy Management Falls Short

  • Reactive fixes – You only notice a proxy is dead after a request fails.
  • Hidden degradation – High latency or packet loss can silently throttle your bots.
  • No visibility – You can’t see which proxy regions or types are performing best.
  • Manual effort – Keeping a spreadsheet of proxy status quickly becomes unsustainable.

A health‑ check system turns this reactive model into a proactive one, giving you real‑time insight and the ability to automatically prune or replace bad nodes.

Core Concepts of Proxy Health Checks

A health check typically consists of three steps:

  1. Select a proxy from your pool (e.g., https://us-roproxy.example.com:8080).
  2. Make a test request through that proxy to a known‑good endpoint (HTTP, HTTPS, or SOCKS5). Common targets are http://httpbin.org/ip, https://api.ipify.org, or an internal service that returns a predictable response.
  3. Record metrics – response time, HTTP status code, success/failure flag, and any error details.

Key metrics to collect:

  • Uptime/Gauge – Is the proxy currently responding?
  • Latency/Histogram – Round‑trip time (RTT) in milliseconds.
  • Success Rate/Counter – Number of successful checks vs. total.
  • Error Count/Counter – Separate counters for HTTP errors, timeouts, connection refusals, etc.

Collecting these numbers lets you spot trends (e.g., a proxy region consistently slower during peak hours) and triggers automated remediation.

Implementing a Health Check Script (Python)

Below is a compact, production‑ready Python script that iterates over a list of RoProxy endpoints, performs an HTTP health check, and publishes Prometheus metrics. It uses prometheus_client and requests (install with pip install prometheus_client requests).

#!/usr/bin/env python3
import time
import requests
from prometheus_client import start_http_server, Counter, Histogram, Gauge
from prometheus_client.core import CollectorRegistry

# Configuration
PROXY_LIST = [
    "https://us-roproxy.example.com:8080",
    "https://eu-roproxy.example.com:8080",
    "https://apac-roproxy.example.com:8080",
]
TEST_URL = "https://httpbin.org/ip"          # public echo service
CHECK_INTERVAL = 30                         # seconds
METRICS_PORT = 8000

# Prometheus metrics
registry = CollectorRegistry()
PROXY_UP = Gauge('proxy_up', '1 if proxy is reachable, 0 otherwise', ['proxy'], registry=registry)
PROXY_LATENCY = Histogram('proxy_latency_seconds', 'Latency of proxy health checks', ['proxy'], buckets=(0.1,0.5,1,2,5,10), registry=registry)
PROXY_SUCCESS = Counter('proxy_success_total', 'Total successful health checks', ['proxy'], registry=registry)
PROXY_FAILURE = Counter('proxy_failure_total', 'Total failed health checks', ['proxy'], registry=registry)

# Start metrics HTTP server
start_http_server(METRICS_PORT, registry=registry)

print(f"Proxy health checker started on :{METRICS_PORT}")

while True:
    for proxy_url in PROXY_LIST:
        # Build requests session with the proxy
        session = requests.Session()
        session.proxies = {"http": proxy_url, "https": proxy_url}
        start = time.monotonic()
        try:
            resp = session.get(TEST_URL, timeout=10)
            elapsed = time.monotonic() - start
            if resp.status_code == 200:
                PROXY_UP.labels(proxy=proxy_url).set(1)
                PROXY_LATENCY.labels(proxy=proxy_url).observe(elapsed)
                PROXY_SUCCESS.labels(proxy=proxy_url).inc()
                print(f"[OK] {proxy_url} – {elapsed:.3f}s")
            else:
                PROXY_UP.labels(proxy=proxy_url).set(0)
                PROXY_FAILURE.labels(proxy=proxy_url).inc()
                print(f"[WARN] {proxy_url} returned {resp.status_code}")
        except Exception as e:
            PROXY_UP.labels(proxy=proxy_url).set(0)
            PROXY_FAILURE.labels(proxy=proxy_url).inc()
            print(f"[ERR] {proxy_url} – {e}")
    time.sleep(CHECK_INTERVAL)

How it works

  • The script runs an HTTP server on port 8000. Prometheus will scrape /metrics from this endpoint.
  • Each proxy is labeled, so you can filter by region or pool in dashboards.
  • Successful checks increment proxy_success_total and set proxy_up to 1; failures set proxy_up to 0 and increment proxy_failure_total. Latency is recorded in a histogram for percentile analysis.

You can schedule this script with a systemd timer or cron (*/30 * * * * /usr/local/bin/proxy_health.py).

Extending to Node.js (Optional)

If your infrastructure is Node‑based, a similar pattern works with axios and prom-client.

const axios = require('axios');
const prom = require('prom-client');

const registry = new prom.Registry();
prom.collectDefaultMetrics({ registry });

const proxyUp = new prom.Gauge({
  name: 'proxy_up',
  help: '1 if proxy is reachable, 0 otherwise',
  labelNames: ['proxy'],
  registers: [registry],
});
const proxyLatency = new prom.Histogram({
  name: 'proxy_latency_seconds',
  help: 'Latency of proxy health checks',
  labelNames: ['proxy'],
  buckets: [0.1,0.5,1,2,5,10],
  registers: [registry],
});
const proxySuccess = new prom.Counter({
  name: 'proxy_success_total',
  help: 'Total successful health checks',
  labelNames: ['proxy'],
  registers: [registry],
});
const proxyFailure = new prom.Counter({
  name: 'proxy_failure_total',
  help: 'Total failed health checks',
  labelNames: ['proxy'],
  registers: [registry],
});

const PROXY_LIST = [
  'https://us-roproxy.example.com:8080',
  'https://eu-roproxy.example.com:8080',
];
const TEST_URL = 'https://httpbin.org/ip';

async function healthCheck() {
  for (const proxy of PROXY_LIST) {
    const session = axios.create({ proxy });
    const start = Date.now();
    try {
      const resp = await session.get(TEST_URL, { timeout: 10000 });
      const elapsed = (Date.now() - start) / 1000;
      if (resp.status === 200) {
        proxyUp.labels({ proxy }).set(1);
        proxyLatency.labels({ proxy }).observe(elapsed);
        proxySuccess.labels({ proxy }).inc();
        console.log(`[OK] ${proxy} - ${elapsed.toFixed(3)}s`);
      } else {
        proxyUp.labels({ proxy }).set(0);
        proxyFailure.labels({ proxy }).inc();
      }
    } catch (e) {
      proxyUp.labels({ proxy }).set(0);
      proxyFailure.labels({ proxy }).inc();
      console.log(`[ERR] ${proxy} - ${e.message}`);
    }
  }
}

setInterval(healthCheck, 30000);

The Node script can be run with node proxy_health.js and exposes metrics on the default /metrics endpoint (if you enable the HTTP server via prom-client or a lightweight wrapper).

Exporting Metrics for Prometheus

Prometheus expects metrics in its exposition format (plain text). Both the Python and Node examples use official client libraries, which automatically format counters, gauges, and histograms correctly.

Key points

  • Labeling: Using proxy as a label lets you separate regions, types (residential vs datacenter), or any custom grouping.
  • Buckets: The histogram buckets give you latency percentiles; you can adjust them based on your tolerance.
  • Service discovery: If you run many health‑check instances behind a load balancer, Prometheus can discover them via the /metrics endpoint.

Setting Up Prometheus

  1. Download and run
    wget https://github.com/prometheus/prometheus/releases/download/v2.48.0/prometheus-2.48.0.linux-amd64.tar.gz
    tar xzf prometheus-2.48.0.linux-amd64.tar.gz
    ./prometheus-2.48.0.linux-amd64/prometheus --config.file=prometheus.yml
    
  2. Create a minimal prometheus.yml
    global:
      scrape_interval: 15s
    
    scrape_configs:
      - job_name: 'proxy-health'
        static_configs:
          - targets: ['localhost:8000']
    
    Adjust targets to match the port your health‑check script listens on.
  3. Verify scraping – Visit http://localhost:9090/targets in the Prometheus UI to confirm the job is up.

Building a Grafana Dashboard

  1. Install Grafana (Docker is easiest):
    docker run -d -p 3000:3000 grafana/grafana
    
  2. Add Prometheus as a data source – Use http://localhost:9090 as the URL.
  3. Create dashboard – Use the "Plus" button > "Dashboard". Add panels:
    • Proxy Uptime – Graph of proxy_up (average over time) with a per‑proxy legend.
    • Latency Distribution – Histogram summary of proxy_latency_seconds (use "Time series" and select proxy_latency_seconds_bucket).
    • Success vs Failure – Stat panel showing proxy_success_total and proxy_failure_total rates.
    • Error Rate – Calculate (proxy_failure_total / (proxy_success_total + proxy_failure_total)) * 100 in the query.

You can add alerts, e.g., "If proxy_up drops below 0.9 for 5 minutes, send a notification to Slack.

Automation and Integration

Scheduled Execution

  • Systemd timer (Linux):
    [Unit]
    Description=Run proxy health checks
    
    [Timer]
    OnCalendar=*:0/30
    Persistent=true
    
    [Install]
    WantedBy=timers.target
    
    systemctl enable --now proxy-health.timer
    
  • Cron (any OS) – */30 * * * * /usr/local/bin/proxy_health.py

Automatic Pool Pruning

Based on the proxy_up gauge, you can write a secondary script that removes any proxy with proxy_up == 0 for more than, say, three consecutive checks. This prevents dead nodes from accumulating in your rotation logic.

Leveraging RoProxy for Reliable Checks

RoProxy’s infrastructure is designed for high availability and low jitter, which means your health‑check requests are less likely to be dropped or delayed by the underlying network. When configuring the proxy URLs, use the provided authentication tokens (e.g., https://us.roproxy.com:8080?key=YOUR_KEY). This ensures each check authenticates correctly and you get accurate latency measurements.

Best Practices

  • Rate limit health checks – Do not exceed 1‑2 checks per proxy per minute to avoid generating unnecessary load.
  • Multi‑target verification – Test against a few different endpoints (e.g., httpbin.org/ip and https://api.ipify.org) to catch endpoint‑specific issues.
  • Geographic spread – If your pool spans multiple regions, keep at least one check per region to catch regional outages.
  • Sticky sessions – When using proxies that maintain cookies or sessions, reuse the same proxy for the duration of a logical operation to avoid login failures.
  • Secure metric endpoint – Bind the metrics server to localhost (127.0.0.1) and expose it only through a firewall or VPN if possible.

Troubleshooting Common Issues

Symptom Likely Cause Fix
proxy_up stays 0 Proxy endpoint unreachable, authentication token invalid, or network firewall blocking. Verify the proxy URL, ensure the token is correct, check if the target IP is allowed.
Latency spikes >2 s Congested backbone or routing issues. Try a different region, or use a backup proxy from another ISP.
Metrics not appearing in Prometheus Scrape interval too short, wrong port, or script not started. Confirm the health‑check process is running and the Prometheus job points to the correct port.
Grafana panels empty Data source misconfigured or query syntax wrong. Double‑check the Prometheus URL and ensure the metric names match exactly (case‑sensitive).

If you continue to see repeated failures, consider adding a "circuit breaker" pattern in your client code – stop sending requests to a proxy after a threshold of errors within a time window.

Conclusion

Health checks and visual monitoring turn a static proxy pool into a living, breathing component of your automation stack. By defining clear metrics, automating periodic checks, and feeding the results into Prometheus and Grafana, you gain immediate visibility into reliability, can react to degradations in seconds, and keep your scraping, testing, or multi‑account workflows uninterrupted.

The provided Python (and optional Node) scripts give you a ready‑to‑run foundation. Pair them with RoProxy’s stable endpoints, and you’ll find the monitoring overhead minimal while the operational confidence is maximal. With dashboards that refresh in real time and alerts that fire on the first sign of trouble, you can focus on building great products rather than firefighting proxy outages.

Start implementing today, and let your proxy pool work as hard as your automation logic does.