Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Ggml org Llama cpp Server Health Metrics

From Leeroopedia
Field Value
Implementation Name Server Health Metrics
Doc Type API Doc
Domain Monitoring, Observability, Prometheus
Description Health, metrics, and slots monitoring endpoints: /health, /metrics, /slots
Related Workflow OpenAI_Compatible_Server

Overview

Description

The Server Health Metrics implementation provides three monitoring endpoints within the llama-server route handlers. The /health endpoint returns a simple status check, /metrics exposes Prometheus-formatted performance counters and gauges, and /slots returns detailed per-slot state information. These are implemented as lambda handlers in server_routes::init_routes().

Usage

# Health check (always available, no auth required)
curl http://localhost:8080/health

# Prometheus metrics (requires --metrics flag)
curl http://localhost:8080/metrics

# Slot inspection (requires --slots flag)
curl http://localhost:8080/slots

Code Reference

Field Value
Source Location tools/server/server-context.cpp:3183-3375
Entry Function void server_routes::init_routes() (health, metrics, and slots handler lambdas)
Import Part of server-context static library

Health endpoint (/health):

this->get_health = [this](const server_http_req &) {
    // error and loading states are handled by middleware
    auto res = create_response(true);

    // this endpoint can be accessed during sleeping
    bool ctx_server; // do NOT delete this line
    GGML_UNUSED(ctx_server);

    res->ok({{"status", "ok"}});
    return res;
};

Metrics endpoint (/metrics):

this->get_metrics = [this](const server_http_req & req) {
    auto res = create_response();
    if (!params.endpoint_metrics) {
        res->error(format_error_response("This server does not support metrics endpoint. Start it with `--metrics`", ERROR_TYPE_NOT_SUPPORTED));
        return res;
    }

    // request slots data using task queue
    {
        server_task task(SERVER_TASK_TYPE_METRICS);
        task.id = res->rd.get_new_id();
        res->rd.post_task(std::move(task), true); // high-priority task
    }

    auto result = res->rd.next(req.should_stop);
    // ... cast to server_task_result_metrics and format

    json all_metrics_def = json {
        {"counter", {{
            {"name",  "prompt_tokens_total"},
            {"help",  "Number of prompt tokens processed."},
            {"value",  (uint64_t) res_task->n_prompt_tokens_processed_total}
        }, /* ... more counters ... */ }},
        {"gauge", {{
            {"name",  "prompt_tokens_seconds"},
            {"help",  "Average prompt throughput in tokens/s."},
            {"value",  res_task->n_prompt_tokens_processed ? 1.e3 / res_task->t_prompt_processing * res_task->n_prompt_tokens_processed : 0.}
        }, /* ... more gauges ... */ }}
    };

    // Format as Prometheus text
    std::stringstream prometheus;
    for (const auto & el : all_metrics_def.items()) {
        const auto & type = el.key();
        for (const auto & metric_def : el.value()) {
            prometheus << "# HELP llamacpp:" << name << " " << help << "\n"
                       << "# TYPE llamacpp:" << name << " " << type << "\n"
                       << "llamacpp:" << name << " " << value << "\n";
        }
    }

    res->content_type = "text/plain; version=0.0.4";
    res->status = 200;
    res->data = prometheus.str();
    return res;
};

Slots endpoint (/slots):

this->get_slots = [this](const server_http_req & req) {
    auto res = create_response();
    if (!params.endpoint_slots) {
        res->error(format_error_response("This server does not support slots endpoint. Start it with `--slots`", ERROR_TYPE_NOT_SUPPORTED));
        return res;
    }

    // request slots data using task queue
    {
        server_task task(SERVER_TASK_TYPE_METRICS);
        task.id = res->rd.get_new_id();
        res->rd.post_task(std::move(task), true);
    }

    auto result = res->rd.next(req.should_stop);
    // ... cast to server_task_result_metrics

    // optionally return "fail_on_no_slot" error
    if (!req.get_param("fail_on_no_slot").empty()) {
        if (res_task->n_idle_slots == 0) {
            res->error(format_error_response("no slot available", ERROR_TYPE_UNAVAILABLE));
            return res;
        }
    }

    res->ok(res_task->slots_data);
    return res;
};

I/O Contract

Endpoint Method Prerequisites Response Content-Type Response Body
/health GET None (always available) application/json {"status": "ok"}
/v1/health GET None (always available) application/json {"status": "ok"}
/metrics GET --metrics flag text/plain; version=0.0.4 Prometheus exposition format text
/slots GET --slots flag application/json JSON array of slot state objects

Prometheus metrics output format:

# HELP llamacpp:prompt_tokens_total Number of prompt tokens processed.
# TYPE llamacpp:prompt_tokens_total counter
llamacpp:prompt_tokens_total 15234

# HELP llamacpp:tokens_predicted_total Number of generation tokens processed.
# TYPE llamacpp:tokens_predicted_total counter
llamacpp:tokens_predicted_total 8921

# HELP llamacpp:prompt_tokens_seconds Average prompt throughput in tokens/s.
# TYPE llamacpp:prompt_tokens_seconds gauge
llamacpp:prompt_tokens_seconds 1523.7

# HELP llamacpp:predicted_tokens_seconds Average generation throughput in tokens/s.
# TYPE llamacpp:predicted_tokens_seconds gauge
llamacpp:predicted_tokens_seconds 42.3

# HELP llamacpp:requests_processing Number of requests processing.
# TYPE llamacpp:requests_processing gauge
llamacpp:requests_processing 2

# HELP llamacpp:requests_deferred Number of requests deferred.
# TYPE llamacpp:requests_deferred gauge
llamacpp:requests_deferred 0

Complete counter metrics:

Metric Name Type Description
llamacpp:prompt_tokens_total counter Cumulative prompt tokens processed
llamacpp:prompt_seconds_total counter Total prompt processing time (seconds)
llamacpp:tokens_predicted_total counter Cumulative generation tokens
llamacpp:tokens_predicted_seconds_total counter Total generation time (seconds)
llamacpp:n_decode_total counter Total llama_decode() calls
llamacpp:n_tokens_max counter Largest observed n_tokens
llamacpp:n_busy_slots_per_decode counter Average busy slots per decode call

Complete gauge metrics:

Metric Name Type Description
llamacpp:prompt_tokens_seconds gauge Current prompt throughput (tokens/s)
llamacpp:predicted_tokens_seconds gauge Current generation throughput (tokens/s)
llamacpp:requests_processing gauge Currently active requests
llamacpp:requests_deferred gauge Queued/deferred requests

Usage Examples

Prometheus scrape configuration:

scrape_configs:
  - job_name: 'llama-server'
    scrape_interval: 15s
    static_configs:
      - targets: ['localhost:8080']
    metrics_path: '/metrics'

Health check with fail_on_no_slot for load balancing:

# Returns 503 if all slots are busy
curl -f "http://localhost:8080/slots?fail_on_no_slot=1" || echo "Server is at capacity"

Kubernetes liveness and readiness probes:

livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 10
readinessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 60

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment