Framework Guide

Flask API Monitoring

Set up health check endpoints and uptime monitoring for your Flask application. Simple patterns for production-ready monitoring.

Simple Health Endpoint

from flask import Flask, jsonify
from datetime import datetime

app = Flask(__name__)

@app.route('/health')
def health():
    return jsonify({
        'status': 'healthy',
        'timestamp': datetime.utcnow().isoformat()
    })

With Database Check

from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
import time

app = Flask(__name__)
db = SQLAlchemy(app)

@app.route('/health')
def health():
    return jsonify({'status': 'healthy'})

@app.route('/ready')
def ready():
    checks = {}
    healthy = True

    # Check database
    try:
        start = time.time()
        db.session.execute('SELECT 1')
        checks['database'] = {
            'status': 'ok',
            'response_time_ms': round((time.time() - start) * 1000, 2)
        }
    except Exception as e:
        healthy = False
        checks['database'] = {
            'status': 'error',
            'message': str(e)
        }

    status_code = 200 if healthy else 503
    return jsonify({
        'status': 'healthy' if healthy else 'unhealthy',
        'timestamp': datetime.utcnow().isoformat(),
        'checks': checks
    }), status_code

Blueprint for Health Checks

# health.py
from flask import Blueprint, jsonify, current_app
from datetime import datetime
import time

health_bp = Blueprint('health', __name__)

@health_bp.route('/health')
def health():
    return jsonify({'status': 'healthy'})

@health_bp.route('/ready')
def ready():
    from extensions import db, redis_client

    checks = {}
    healthy = True

    # Database check
    try:
        start = time.time()
        db.session.execute('SELECT 1')
        checks['database'] = {
            'status': 'ok',
            'response_time_ms': round((time.time() - start) * 1000, 2)
        }
    except Exception as e:
        healthy = False
        checks['database'] = {'status': 'error', 'message': str(e)}

    # Redis check
    try:
        start = time.time()
        redis_client.ping()
        checks['redis'] = {
            'status': 'ok',
            'response_time_ms': round((time.time() - start) * 1000, 2)
        }
    except Exception as e:
        healthy = False
        checks['redis'] = {'status': 'error', 'message': str(e)}

    return jsonify({
        'status': 'healthy' if healthy else 'unhealthy',
        'checks': checks,
        'version': current_app.config.get('VERSION', 'unknown')
    }), 200 if healthy else 503

# app.py
from health import health_bp
app.register_blueprint(health_bp)

Using flask-healthz

# Install
pip install flask-healthz

# app.py
from flask import Flask
from flask_healthz import healthz, HealthError

app = Flask(__name__)

def liveness():
    pass  # Just needs to not raise

def readiness():
    try:
        db.session.execute('SELECT 1')
    except Exception:
        raise HealthError("Database not ready")

app.register_blueprint(healthz, url_prefix="/health")
app.config['HEALTHZ'] = {
    "live": liveness,
    "ready": readiness,
}

Exclude from Logging

# Prevent health checks from cluttering logs
import logging

class HealthCheckFilter(logging.Filter):
    def filter(self, record):
        return '/health' not in record.getMessage()

# Apply to werkzeug logger
logging.getLogger('werkzeug').addFilter(HealthCheckFilter())

Best Practices

  • Use blueprints — Keep health checks organized and reusable
  • Check all dependencies — Database, cache, external APIs
  • Add timeouts — Don't let slow checks hang the endpoint
  • Return proper status codes — 200 for healthy, 503 for unhealthy

Monitor your Flask API

Add your health endpoint to UptimeSignal and get alerted when it fails.

Start monitoring free →

More Framework Guides