# Usage and storage > What a namespace has spent per key and per model, what it is holding, and why accepted submissions and provider calls are different numbers. Source: https://docs.stg.perdurance.dev/usage/ --- Two routes, both scoped to a namespace and both needing a key that can manage it. ## `GET /usage` What the namespace has spent, in total and attributed per key. ```bash curl "$PERDURANCE_URL/usage" -H "Authorization: Bearer $PERDURANCE_KEY" ``` ```json { "namespace_id": "…", "itemised_since": 1787900000000, "accepted_submissions": 1841, "provider_calls": 1792, "upstream_sent_bytes": 4192048, "upstream_received_bytes": 19402881, "api_keys": [ { "api_key_id": "…", "ledger_events": 1204, "provider_calls": 1180, "prompt_tokens": 884102, "completion_tokens": 219884, "total_tokens": 1103986 } ] } ``` **`accepted_submissions` and `provider_calls` are deliberately different numbers.** A submission that landed on an existing execution inside the idempotency window is counted once as a submission and not at all as a provider call. The gap between them is what deduplication saved you. `itemised_since` is the oldest event the per-key breakdown covers. The totals above it are all-time; the `api_keys` list is only as deep as retention has kept. A token count is `null` where no answer under that key reported one, which is not the same as a provider reporting zero. Treat `null` as "not known", not as "none". ### Attribution Every figure in `api_keys` is per key, which is what makes a key the unit of cost accounting. Issue one per service, per environment, or per customer, and this route tells you what each of them spent without a second system. ## `GET /storage` What the namespace is currently holding, and where it went. ```bash curl "$PERDURANCE_URL/storage" -H "Authorization: Bearer $PERDURANCE_KEY" ``` ```json { "namespace_id": "…", "stored_bytes": 20418302, "request_bytes": 4192048, "response_bytes": 2884102, "chunk_bytes": 13342152 } ``` `stored_bytes` is the sum of the other three. The split matters because they grow for different reasons: `request_bytes` tracks how much you send, `response_bytes` how much comes back whole, and `chunk_bytes` how much comes back streamed — which is usually the largest, because a streamed answer is stored as its individual frames so it can be replayed and resumed. ### Keeping it down Retention is a **namespace** setting, in minutes, and it is unset by default — which means every record is kept until you say otherwise. Set it in the console under Namespaces, or with `PATCH /{tenancy}/v1/namespaces/{namespace}`. A namespace that names no horizon takes its tenancy's; a namespace that names `0` keeps everything even where its tenancy sweeps. What a sweep takes is the **record**: the request body, the answer, and the chunks. What it leaves is everything you bill and report from — the status, the model, the token counts, the cost, the timings, and the fee ledger. Those have their own, much longer horizons, set for the whole deployment rather than per namespace. So shortening a namespace's retention bounds your disk without costing you the ability to reconstruct an invoice. Retrieving a swept record answers `410 Gone` rather than `404 Not Found`, because the request did happen and everything about what it did is still there. Lapsed idempotency claims are swept whatever retention says, because a claim is not a record. Per-request sizes are also in the listing: `GET /requests` gives `stored_bytes` per row, which is how you find the handful of requests holding most of it.