Simple Health Check Endpoint — Complete Implementation Guide
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
Returning 200 for all HTTP methods -- Health check endpoints should only respond to GET requests. Return 405 Method Not Allowed for other methods.
Caching the health check response -- Health checks must reflect real-time status. Set Cache-Control: no-cache headers to prevent caching.
Including sensitive information in the response -- Never expose environment variables, internal IPs, or configuration details in health check responses.
Not setting a Content-Type header -- Tools and orchestrators expect JSON. Always set Content-Type: application/json.
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
What HTTP status code should a healthy endpoint return? 200 OK. Non-200 statuses (especially 503) indicate the service is unhealthy.
What fields should a basic health check response include? Status, service name, version, uptime, and timestamp. Keep it simple for the basic check.
How do Docker health checks work? Docker runs the HEALTHCHECK command inside the container. Exit code 0 means healthy, exit code 1 means unhealthy.
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
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