/metrics serves the Prometheus text format, unauthenticated like the probes — an orchestrator scraping it has no forge token, and refusing it would only mean the one moment you need numbers is the one moment you cannot get them.

Metric Kind Answers
lfsx_requests_total{route,status} counter what is being served, and what is failing
lfsx_request_duration_seconds{route} histogram how long transfers take
lfsx_uploaded_bytes_total, lfsx_downloaded_bytes_total counter throughput in and out
lfsx_object_size_bytes histogram what people are actually storing
lfsx_rejections_total{cause} counter why requests are refused, by cause rather than by status
lfsx_objects_stored, lfsx_store_bytes gauge how full the disk is getting, counting shared objects once
lfsx_store_scans gauge how often the expensive walk behind those two actually ran

Routes are labelled by their template, never by the path, so the object id can never turn into a label and the series count stays bounded whatever you store.

Those two count what the disk holds, not what the repositories logically hold: an object shared by three projects is one set of bytes and is counted once. The per-repository page reports logical size instead, since "this project uses 3 GiB of assets" is the useful answer there even when some of it is shared.

The two disk gauges are measured by walking the store, so they are computed at most once a minute and reused in between — and concurrent scrapes queue behind a single walk rather than each starting their own, which is what keeps an unauthenticated endpoint from being a lever on a large disk. lfsx_store_scans is how you check that: it should climb about once a minute under load, not once per request.

lfsx_downloaded_bytes_total counts bytes as they are streamed, so a client that disconnects halfway is not recorded as a full download.