Render service dashboard showing deployment status, health checks and service logs with external monitoring alerts
# developer tools# website monitoring

How to Monitor Render Services and Background Workers

Render has grown into a serious platform for deploying web services, background workers, cron jobs, and databases. Its automatic deployments, built-in SSL, and managed infrastructure remove a lot of operational overhead.

But like any hosting platform, Render's internal tooling shows you what's happening inside your service — not what your users experience from the outside. External monitoring fills that gap.

What Render Provides

Render includes:

  • Deployment logs and build status
  • HTTP request logs
  • Basic metrics (CPU, memory)
  • Health check configuration for web services
  • Automatic SSL
  • Auto-deploy from Git

What Render doesn't provide:

  • External availability checks from multiple global locations
  • Response content validation
  • Alerts when a specific endpoint starts returning errors
  • SSL certificate expiry notifications

Render's Built-In Health Checks

Render supports health check configuration for web services. In your service settings, you can specify a health check path and Render will check it before routing traffic to a new deployment.

This is valuable for preventing broken deployments from going live. But it only runs at deploy time — it doesn't continuously monitor your application after deployment.

Configure it in your service settings:

  • Health Check Path: /health
  • Health Check Grace Period: enough time for your application to start

With this configured, Render won't mark a deployment as live if the health check fails. A deploy that crashes immediately won't get traffic.

Health Check Endpoint Patterns

Minimal check — Confirms the application is responding:

# FastAPI
@app.get('/health')
async def health():
    return {'status': 'ok'}
# Rails
get '/health', to: proc { [200, {}, ['ok']] }

Dependency check — Confirms the database and cache are reachable:

@app.get('/health/deep')
async def deep_health(db: AsyncSession = Depends(get_db)):
    try:
        await db.execute(text('SELECT 1'))
        return {'status': 'ok', 'database': 'ok'}
    except Exception as e:
        raise HTTPException(status_code=503, detail=str(e))

Use the minimal check for Render's built-in health check (fast, no dependencies) and the deep check for your external monitoring that you want to check more thoroughly.

Monitoring Background Workers

Render's background workers are services without a public port — they process jobs, run tasks, or perform background computation. When a background worker fails, Render restarts it, but there's no HTTP endpoint to check externally.

Heartbeat Monitoring

The standard approach is heartbeat monitoring: your worker pings a URL at regular intervals to confirm it's alive. If the ping stops coming, an alert fires.

import httpx
import asyncio

async def process_jobs():
    while True:
        try:
            job = await queue.dequeue()
            await process(job)

            # Ping heartbeat after each successful batch
            async with httpx.AsyncClient() as client:
                await client.get('https://your-heartbeat-url')

        except Exception as e:
            logger.error(f'Worker error: {e}')
            await asyncio.sleep(5)

See how to monitor cron jobs for detailed heartbeat monitoring setup.

Health HTTP Server Alongside Worker

For workers that need more than a heartbeat, run a minimal HTTP server alongside the worker process:

import threading
from http.server import HTTPServer, BaseHTTPRequestHandler

class HealthHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/health':
            self.send_response(200)
            self.end_headers()
            self.wfile.write(b'{"status": "ok"}')

    def log_message(self, format, *args):
        pass  # Suppress access logs

def start_health_server():
    server = HTTPServer(('0.0.0.0', 8080), HealthHandler)
    server.serve_forever()

# Start health server in background thread
threading.Thread(target=start_health_server, daemon=True).start()

# Main worker loop
run_worker()

Set a PORT environment variable on Render and point monitoring at /health on that port.

Monitoring Render Cron Jobs

Render's cron job service runs commands on a schedule. When a cron job fails, Render logs the failure — but you won't know unless you check the logs or set up alerting.

Use post-job pings to an uptime monitor's heartbeat URL:

# Your cron command
python generate_report.py && curl -s https://your-heartbeat-url

The && means the ping only fires if the command succeeds. If it fails, no ping — and your heartbeat monitor fires an alert.

Free Tier and Spin-Up Delays

Render's free tier spins down services after inactivity. The first request after a spin-down period takes significantly longer while the container starts up. This can look like downtime to monitoring tools if the timeout is set too short.

Two options:

  1. Use a paid tier that doesn't spin down
  2. Set your monitoring check timeout to 30+ seconds and accept occasional slow responses

If you're monitoring a free-tier Render service, configure your monitor's timeout accordingly to avoid false positive alerts on spin-up delays.

Connecting External Monitoring

Domain Monitor monitors your Render services from multiple global locations, separate from Render's own infrastructure. This means:

  • You get alerts even if Render's own alerting is delayed or missing
  • You catch regional issues that affect some users but not all
  • You have independent verification that your application is working, not just that Render says it is

Create a free account and add your Render service URL. For background workers with a health endpoint, add that URL too. Set the check interval to every minute for production services.

Also in This Series

See how to set up downtime alerts for configuring alert channels, and website monitoring checklist for developers for a complete pre-launch monitoring setup.

More posts

Why Your Status Page Matters During an Outage

When your site goes down, your status page becomes the most important page you have. Here's why it matters, what happens when you don't have one, and what a good status page does during a real outage.

Read more
Why Your Domain Points to the Wrong Server

Your domain is resolving, but pointing to the wrong server — showing old content, a previous host's page, or someone else's site entirely. Here's what causes this and how to diagnose it.

Read more
Why Website Monitoring Misses Downtime Sometimes

Uptime monitoring isn't foolproof. Single-location monitors, wrong health check endpoints, long check intervals, and false positives can all cause real downtime to go undetected. Here's what to watch out for.

Read more

Subscribe to our PRO plan.

Looking to monitor your website and domains? Join our platform and start today.