> ## Documentation Index
> Fetch the complete documentation index at: https://headgate.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Show fleet capacity and queues with no live workers.

> The registry answers "what is each worker doing"; this answers the fleet-level
question an operator asks during an incident. A queue with a growing backlog and
no consumer looks exactly like a slow queue until you know it is unserved, so
`queues` lists every queue the store knows about UNIONED with every queue a live
worker claims — an unserved queue appears WITH `live_workers: 0` rather than
being absent, because "not in the list" is indistinguishable from "not looked
at". Staleness uses the same 15-minute heartbeat grace as `GET /workers`.

Autoscaling signals ride along: `utilization` = inflight/capacity and
`empty_poll_ratio` = admits returning zero / total admits over each worker's
rolling window. Both are ratios of SUMS, not averages of per-worker ratios, so a
1-slot worker does not weigh the same as a 64-slot one. Scale UP on high
utilization with a growing time-to-drain; scale DOWN on a high empty-poll ratio.
headgate publishes the signal and never sizes the fleet.




## OpenAPI

````yaml /api/headgate.openapi.yaml get /cluster
openapi: 3.1.0
info:
  title: headgate control API
  version: 0.1.0
  description: >
    The web UI is one client of this control API and gets no

    privileged access — asynqmon reads Redis directly, which is why its
    compatibility

    note is three minor versions stale.


    Both the Go and Rust implementations serve this spec, and the conformance
    suite

    asserts identical responses. Every list endpoint is bounded to prevent
    inspection

    from becoming an unbounded store operation: asynq's

    GetQueueInfo is O(number of groups) and has pinned Redis CPU for seconds in

    production. Monitoring caused the outage.


    DERIVED FROM THE ARCHITECTURE, NOT FROM A PREDECESSOR'S UI. The first draft
    of this

    spec was the asynq Inspector surface -- list by state, act on one job, pause
    a queue

    -- with new nouns bolted on. That inherited three problems: it omitted bulk

    operations, history, and enqueue (which asynq and apalis-board respectively
    DO have),

    and more importantly it had no endpoint for the question this system's own
    design

    creates. When dequeue is an admission decision, the operator's first
    question is not

    "what is in the queue" but "why is THIS job not running" -- see
    /jobs/{id}/admission.

    No predecessor needs that endpoint because no predecessor has a gate.
servers:
  - url: /api/v1
security: []
paths:
  /cluster:
    get:
      summary: Show fleet capacity and queues with no live workers.
      description: >
        The registry answers "what is each worker doing"; this answers the
        fleet-level

        question an operator asks during an incident. A queue with a growing
        backlog and

        no consumer looks exactly like a slow queue until you know it is
        unserved, so

        `queues` lists every queue the store knows about UNIONED with every
        queue a live

        worker claims — an unserved queue appears WITH `live_workers: 0` rather
        than

        being absent, because "not in the list" is indistinguishable from "not
        looked

        at". Staleness uses the same 15-minute heartbeat grace as `GET
        /workers`.


        Autoscaling signals ride along: `utilization` = inflight/capacity and

        `empty_poll_ratio` = admits returning zero / total admits over each
        worker's

        rolling window. Both are ratios of SUMS, not averages of per-worker
        ratios, so a

        1-slot worker does not weigh the same as a 64-slot one. Scale UP on high

        utilization with a growing time-to-drain; scale DOWN on a high
        empty-poll ratio.

        headgate publishes the signal and never sizes the fleet.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  workers:
                    type: object
                    properties:
                      live:
                        type: integer
                      stale:
                        type: integer
                      total:
                        type: integer
                  capacity_total:
                    type: integer
                  inflight_total:
                    type: integer
                  utilization:
                    type: number
                  empty_poll_ratio:
                    type: number
                  polls_total:
                    type: integer
                  empty_polls_total:
                    type: integer
                  queues:
                    type: array
                    items:
                      type: object
                      properties:
                        queue:
                          type: string
                        live_workers:
                          type: integer

````