Skip to main content
Version: 0.12.0

Monitoring memory usage and data residency

Introduced 0.12.0

Memory keeps its own meter. A single endpoint reports, per organization, three things you need for billing and compliance: the storage footprint of the organization's memory indices, the embedding (AI) usage — provider calls and the exact tokens billed — and the trust-boundary egress: how much memory content, and how many tokens, left the cluster to a managed third-party embedding service. That last figure is the data-residency signal for controls like FedRAMP SC-7 (boundary protection) and HIPAA.

tip

The usage endpoint is identity-scoped by default: GET /_plugins/_memory/usage reports your own organization, sourced from your verified identity — never a request parameter. Reading another organization, or every organization at once, is a separate admin-gated route.


Table of contents


The endpoints

There is one usage surface, with an identity-scoped self route and two admin routes. All are GET and take no body.

MethodPathScopeRole
GET/_plugins/_memory/usageThe caller's own organization (org from the verified identity).memory_read
GET/_plugins/_memory/usage/{org}One named organization.memory_full_access
GET/_plugins/_memory/usage/_allEvery provisioned organization.memory_full_access
note

The self route is granted by memory_read (via the cluster permission cluster:admin/lucenia/memory/usage) and is therefore available to any read or read-write memory user — a tenant can always see its own bill. Both admin routes are the single permission cluster:admin/lucenia/memory/usage/all, held only by memory_full_access, so a tenant cannot use {org} or _all to read another organization's usage. See Enable and configure memory for the role model.

Your own organization

GET /_plugins/_memory/usage
Authorization: ApiKey azLThjJhLi4uLi4uOnNlY3JldA==

A named organization (admin)

GET /_plugins/_memory/usage/acme

Every organization (admin)

GET /_plugins/_memory/usage/_all

Every variant returns the same shape: an orgs array with one entry per organization (a single entry for the self and named-org routes).

What it reports

1. Storage footprint

For each backing index the organization owns, the report gives a document count and the on-disk store_bytes — the basis for billing by storage. An organization has one long-term index per embedding model it uses (each carries its own model slug), plus one working (episodic) index and one drift-anchors index:

kindIndexmodel
long_term.plugins-memory-longterm-<org>__<model-slug>the embedding model id
working.plugins-memory-working-<org>(omitted — working memory stores no vector)
anchors.plugins-memory-anchors-<org>(omitted)

The organization's total_docs and total_store_bytes sum across all of its indices. (Each store's per-organization physical isolation is described in Memory tenancy and isolation.)

2. Embedding (AI) usage and tokens

The embedding array carries one counter row per (model, provider, destination) the organization embedded through. Each row reports provider calls, the number of items embedded (texts or images), the exact tokens the provider itself billed, and the content bytes sent.

note

tokens is the provider's own reported token count — the number you are billed on. The managed cloud providers (Bedrock, Vertex, Azure, and OpenAI-compatible HTTP endpoints that return usage) report it exactly. The built-in local hashing embedder and image embeddings have no provider token count, so their rows report tokens: 0 (their items and bytes still count).

3. Trust-boundary egress

Each embedding row is classified by where the content went — egress_kind — and the roll-up egress object sums whatever crossed the cluster's trust boundary.

egress_kindMeaningleft_trust_boundarydestination example
localThe built-in hashing embedder — computed in-process, nothing leaves the node.falselocal
self_hostedAn in-network HTTP / vLLM endpoint you run — content stays in your network; the host is recorded.falsehttp:vllm.internal.example
external_cloudA managed third-party service (Bedrock, Vertex, Azure) — content left the cluster.truebedrock:us-east-1, vertex:us-central1, azure:acme.openai.azure.com

destination is a low-cardinality label — a host or region only, never a full URL, path, or secret. left_trust_boundary is true only for external_cloud (an unrecognized provider is treated as external_cloud, fail-safe for audit). The egress object then rolls up only the boundary-crossing rows:

  • left_trust_boundary_calls — provider calls that left the boundary
  • left_trust_boundary_tokens — tokens that left the boundary
  • left_trust_boundary_bytes — content bytes that left the boundary

This is the compliance headline: for a fully self-hosted or local deployment every one of these is 0.

Response reference

{
"orgs": [
{
"org": "acme",
"indices": [
{
"index": ".plugins-memory-longterm-acme__amazon-titan-embed-text-v2-0",
"kind": "long_term",
"model": "amazon.titan-embed-text-v2:0",
"docs": 1840,
"store_bytes": 20447232
},
{ "index": ".plugins-memory-working-acme", "kind": "working", "docs": 512, "store_bytes": 1048576 },
{ "index": ".plugins-memory-anchors-acme", "kind": "anchors", "docs": 8, "store_bytes": 32768 }
],
"total_docs": 2360,
"total_store_bytes": 21528576,
"embedding": [
{
"model": "amazon.titan-embed-text-v2:0",
"provider": "bedrock",
"egress_kind": "external_cloud",
"destination": "bedrock:us-east-1",
"left_trust_boundary": true,
"calls": 1840,
"items": 1840,
"tokens": 214880,
"bytes": 987654
}
],
"egress": {
"left_trust_boundary_calls": 1840,
"left_trust_boundary_tokens": 214880,
"left_trust_boundary_bytes": 987654
}
}
]
}

orgs[]

FieldTypeMeaning
orgstringThe organization id.
indicesarrayPer-index storage footprint (below).
total_docslongTotal documents across the organization's indices.
total_store_byteslongTotal on-disk store size across the organization's indices, in bytes.
embeddingarrayPer-(model, provider, destination) embedding counters (below).
egressobjectTrust-boundary roll-up: left_trust_boundary_calls, left_trust_boundary_tokens, left_trust_boundary_bytes.

indices[]

FieldTypeMeaning
indexstringThe concrete backing index name.
kindstringlong_term, working, or anchors.
modelstringEmbedding model id — present only for a long_term index.
docslongDocuments stored in the index.
store_byteslongOn-disk store size of the index, in bytes.

embedding[]

FieldTypeMeaning
modelstringThe embedding model id.
providerstringhashing, http, bedrock, vertex, azure, or azure_vision.
egress_kindstringlocal, self_hosted, or external_cloud.
destinationstringLow-cardinality host or region label (never a URL or secret).
left_trust_boundarybooleantrue only when the destination is a managed third-party cloud.
callslongProvider calls made.
itemslongItems (texts/images) embedded.
tokenslongExact tokens the provider billed (0 for local hashing or image embeddings).
byteslongContent bytes embedded.

Freshness and durability

The counters are durable and cluster-wide. Embedding events accumulate in node-local counters that are periodically flushed into the .plugins-memory-usage system index, so they survive node restarts and are summed across all nodes. The endpoint flushes the live node-local counters before it reads, so a call always returns current, near-real-time numbers rather than only the last periodic checkpoint. Like every memory index, .plugins-memory-usage is a protected system index you never read directly — the usage endpoint reads it for you.

Usage versus stats

Two read-only endpoints are easy to confuse; they answer different questions.

EndpointAnswersReports
GET /_plugins/_memory/usageHow much have we stored and embedded, and what left the boundary?Per-org storage footprint, embedding/token counters, egress roll-up.
GET /_plugins/_memory/statsWhich embedder is active right now?The live embedder config only: mode, dimension, semantic, multimodal.

Use stats to confirm which model recall is using; use usage to see how much it has cost and where the data went. The stats verb is documented in Inference memory.