Health checks of an API: why a 200 OK does not guarantee that it works

Published on 2026-10-26 by frfrand

Designing liveness and readiness checks without saturating the database

Health checks of an API: why a 200 OK does not guarantee that it works

The /health route returns 200 and everyone is happy. But it turns out PostgreSQL is down and not a single reservation can be created. A useful health check must distinguish between "the process is alive" and "I can handle traffic."

Let's get down to brass tacks: what it means, how to test it, and what happens when you use it with clients or real information. Most problems aren't fixed with a magic button, but with steps you can repeat and measure.

What API health checks are and why they matter

Liveness indicates whether it's worth restarting a process that isn't responding; readiness signals whether it's ready to receive requests. Checking all dependencies on every liveness can cause cascading restarts when an external database fails.

One thing is for a demo to work for five minutes and another is to sustain a service every day. For that you need limits, permissions, activity logs, and procedures to resolve failures without improvising.

Implementation or diagnostic example

from fastapi import FastAPI
app = FastAPI()

@app.get('/live')
def live():
    return {'status': 'alive'}

# /ready debería consultar dependencias necesarias con timeout corto
# y devolver 503 si no puede atender trabajo real

It's a didactic reference, not a template you should blindly run in production. Replace the example values, choose identities with minimal permissions, and make sure no sensitive key ends up in a log or repository.

How I would put it into operation

  1. Create a very lightweight liveness endpoint, without relying on a slow query.
  2. Design readiness based on critical dependencies for core functionality.
  3. Use short timeouts to avoid saturating the database during an incident.
  4. Check what the load balancer does upon 503 and how the service recovers.
  5. Add external functional monitoring to verify real operations, not just HTTP 200.

After each step, verify a concrete result: an authorized action, an HTTP status, a processed task, a registered cost, or a stable metric. If something doesn't work, check what the first failure was before retrying in a loop.

An example that may appear in a real project

A tours API responds to /live while it is running, but /ready returns 503 if it cannot query availability via PostgreSQL. This helps the system not send bookings to an instance that cannot handle them.

If that application has multiple clients, separate contexts and resources. It is especially important when a chatbot or an agent can query data: the ease of connecting tools should not bypass privacy and authorization limits.

The most common mistake

Do not perform a costly query on every health check. If all containers query the database several times per second, monitoring can become part of the problem.

A configuration with good defaults helps, but does not eliminate the need for testing. For services that write data or trigger actions, consider retries, duplicates, and midway failures.

Where does ArduMaker come in?

In applications hosted on ArduMaker, combine service state with health checks and external monitoring. A powered-on VPS does not guarantee that the application fulfills its function.

With ArduMaker you can host the backend on a VPS, deploy from Git, configure an HTTPS domain, and use database, service, and MCP tools according to the project. This makes it easier to gather operations in one environment, although business rules and security remain the responsibility of the software.

What I would measure to know if it improved

I would not measure only "works/does not work." I would also review resource consumption, errors, response times, or API usage, depending on the functionality. Define a success metric before the change and compare it with the same scenario afterward.

If a piece of data seems strange, check the sample and the time window. An average can hide extreme cases, and a single successful execution does not demonstrate that an automation can handle thousands of requests.

Frequently asked questions

Do I need a large infrastructure to get started? Not necessarily. First solve the problem with a simple architecture and measure the point where it starts to fall short.

What happens if the external provider fails? You need timeouts, a retry policy, and a useful response for the user. Do not assume external APIs are always available.

How do I maintain control? Log important events, separate permissions, and keep a tested procedure to undo changes or recover information.

References to follow

The final idea: automating and measuring is worth it when you also know how to detect an error, limit its effects, and recover.

  • API
  • Tutorial
  • ArduMaker

Keep reading

All articles · VPS plans