Skip to content

Simple Health Check Endpoint — Complete Implementation Guide

DodaTech Updated 2026-06-28 6 min read

In this tutorial, you will learn about Simple Health Check Endpoint. We cover key concepts, practical examples, and best practices to help you master this topic.

A simple health check endpoint returns a 200 status code with basic service information when the process is running, providing the foundation for more sophisticated health monitoring.

What You'll Learn

By the end of this tutorial, you will know how to implement a simple health check endpoint in multiple languages, format the response, and integrate it with monitoring tools.

Why It Matters

The simple health check is the most basic building block of production readiness. Every service needs at least one. It enables load balancers, orchestrators, and monitoring tools to verify the service is running.

Real-World Use

DodaTech's deployment pipeline runs a health check against every new service instance before adding it to the load balancer. The check must return 200 within 30 seconds of startup.

Simple Health Check Learning Path

flowchart LR
  A[Health Check Types] --> B[Simple Health Check]
  B --> C[Node.js]
  B --> D[Python]
  B --> E[JSON Format]
  B --> F{You Are Here}
  style F fill:#f90,color:#fff

Node.js Simple Health Check

The simplest health check in Node.js uses the built-in http module.

const http = require("http");

const startTime = Date.now();

const server = http.createServer((req, res) => {
  if (req.url === "/healthz") {
    const response = {
      status: "ok",
      service: "my-api",
      version: "1.0.0",
      uptime: Math.floor((Date.now() - startTime) / 1000),
      timestamp: new Date().toISOString()
    };

    res.writeHead(200, {
      "Content-Type": "application/json",
      "Cache-Control": "no-cache"
    });
    res.end(JSON.stringify(response));
  } else {
    res.writeHead(404);
    res.end();
  }
});

server.listen(8080, () => {
  console.log("Simple health check at http://localhost:8080/healthz");
});

// GET /healthz
// HTTP/1.1 200 OK
// Content-Type: application/json
//
// {"status":"ok","service":"my-api","version":"1.0.0","uptime":42,"timestamp":"2026-06-28T12:00:00.000Z"}

Python Simple Health Check

Flask makes it straightforward to add a health check endpoint.

from flask import Flask, jsonify
import time
import os

app = Flask(__name__)
start_time = time.time()

@app.route("/healthz")
def health_check():
    return jsonify({
        "status": "ok",
        "service": "my-api",
        "version": os.environ.get("APP_VERSION", "1.0.0"),
        "uptime": int(time.time() - start_time),
        "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
    }), 200

@app.route("/")
def index():
    return jsonify({"message": "Service is running"}), 200

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

# curl http://localhost:8080/healthz
# {"status":"ok","service":"my-api","version":"1.0.0","uptime":42,"timestamp":"2026-06-28T12:00:00.000Z"}

Go Simple Health Check

Go's standard library provides everything needed for a health endpoint.

package main

import (
    "encoding/json"
    "net/http"
    "time"
    "os"
)

type HealthResponse struct {
    Status    string `json:"status"`
    Service   string `json:"service"`
    Version   string `json:"version"`
    Uptime    int64  `json:"uptime"`
    Timestamp string `json:"timestamp"`
}

var startTime = time.Now()

func healthHandler(w http.ResponseWriter, r *http.Request) {
    version := os.Getenv("APP_VERSION")
    if version == "" {
        version = "1.0.0"
    }

    response := HealthResponse{
        Status:    "ok",
        Service:   "my-api",
        Version:   version,
        Uptime:    int64(time.Since(startTime).Seconds()),
        Timestamp: time.Now().UTC().Format(time.RFC3339),
    }

    w.Header().Set("Content-Type", "application/json")
    w.Header().Set("Cache-Control", "no-cache")
    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(response)
}

func main() {
    http.HandleFunc("/healthz", healthHandler)
    http.ListenAndServe(":8080", nil)
}

// GET /healthz
// {"status":"ok","service":"my-api","version":"1.0.0","uptime":42,"timestamp":"2026-06-28T12:00:00.000Z"}

Spring Boot Simple Health Check

Spring Boot provides built-in health endpoints through Actuator.

# application.yml
management:
  endpoints:
    web:
      exposure:
        include: health
  endpoint:
    health:
      show-details: always
// The /actuator/health endpoint is auto-configured
// No code needed for the basic health check
// Custom health indicators can be added via beans

@Component
public class CustomHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        boolean dbHealthy = checkDatabase();
        if (dbHealthy) {
            return Health.up()
                .withDetail("database", "reachable")
                .build();
        }
        return Health.down()
            .withDetail("database", "unreachable")
            .build();
    }

    private boolean checkDatabase() {
        return true;
    }
}

// GET /actuator/health
// {"status":"UP","components":{"custom":{"status":"UP","details":{"database":"reachable"}}}}

Docker Health Check Directive

Docker supports health checks directly in the Dockerfile or compose file.

# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD node -e "require('http').get('http://localhost:8080/healthz', r => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"
CMD ["node", "server.js"]
# docker-compose.yml
services:
  app:
    image: my-app:latest
    ports:
      - "8080:8080"
    healthcheck:
      test: ["CMD", "node", "-e", "require('http').get('http://localhost:8080/healthz', r => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 10s

Common Mistakes

  1. Returning 200 for all HTTP methods -- Health check endpoints should only respond to GET requests. Return 405 Method Not Allowed for other methods.

  2. Caching the health check response -- Health checks must reflect real-time status. Set Cache-Control: no-cache headers to prevent caching.

  3. Including sensitive information in the response -- Never expose environment variables, internal IPs, or configuration details in health check responses.

  4. Not setting a Content-Type header -- Tools and orchestrators expect JSON. Always set Content-Type: application/json.

  5. Putting health check on the same route as application logic -- Use a dedicated path like /healthz or /health. Don't overload your API routes with health check logic.

Practice Questions

  1. What HTTP status code should a healthy endpoint return? 200 OK. Non-200 statuses (especially 503) indicate the service is unhealthy.

  2. What fields should a basic health check response include? Status, service name, version, uptime, and timestamp. Keep it simple for the basic check.

  3. How do Docker health checks work? Docker runs the HEALTHCHECK command inside the container. Exit code 0 means healthy, exit code 1 means unhealthy.

  4. Challenge: Implement a health check that returns a different status based on the Accept header.

function acceptAwareHealthCheck(req, res) {
  const accept = req.headers.accept || "application/json";
  const data = { status: "ok", uptime: process.uptime() };

  if (accept.includes("application/json")) {
    res.writeHead(200, { "Content-Type": "application/json" });
    res.end(JSON.stringify(data));
  } else if (accept.includes("text/plain")) {
    res.writeHead(200, { "Content-Type": "text/plain" });
    res.end(`status=ok\nuptime=${process.uptime()}`);
  } else {
    res.writeHead(200);
    res.end("ok");
  }
}

FAQ

What is the standard path for health checks?

/healthz is traditional (from Google's convention). /health and /healthz are both common. Choose one and be consistent.

Should the health check be on the same port as the application?

In development, yes. In production, use a separate port (e.g., 8081) so health checks remain available during application port issues.

How often should external monitoring tools check the health endpoint?

Every 30-60 seconds for external monitoring. Every 5-15 seconds for Kubernetes probes.

Should I log every health check request?

No. Health checks run frequently and would flood logs. Log state changes only (healthy -> unhealthy and back).

What happens if the health check itself crashes?

The process crashes, and the orchestrator restarts it. The health check is part of the application, not a separate process.

Mini Project

Build a simple health check server in your language of choice that returns 200 with service info, supports Docker HEALTHCHECK, and includes a health check endpoint that's accessible without authentication.

const http = require("http");

function buildSimpleHealthCheck(port = 8080) {
  const meta = {
    service: "simple-health-check",
    version: "1.0.0",
    startTime: Date.now()
  };

  const server = http.createServer((req, res) => {
    if (req.method !== "GET") {
      res.writeHead(405);
      return res.end();
    }

    if (req.url === "/healthz" || req.url === "/health") {
      const response = {
        status: "ok",
        ...meta,
        uptime: Math.floor((Date.now() - meta.startTime) / 1000),
        timestamp: new Date().toISOString()
      };

      res.writeHead(200, {
        "Content-Type": "application/json",
        "Cache-Control": "no-cache"
      });
      res.end(JSON.stringify(response));
    } else {
      res.writeHead(404);
      res.end();
    }
  });

  server.listen(port, () => {
    console.log(`${meta.service} v${meta.version} listening on :${port}/healthz`);
  });

  return server;
}

buildSimpleHealthCheck();

What's Next

Now that you have a simple health check, expand it with dependency health checks that verify downstream services. Then implement deep health checks.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro