Storage
Rustrak accumulates data fast — every error event, transaction, span, and source map adds up. The Storage page lets an admin see exactly what the instance is holding and reclaim space by deleting old data, much like a server’s disk-cleanup tools.
Storage is instance-admin only. Members never see it, and every cleanup is destructive, so it lives behind the admin gate.
Where to find it
Go to Settings → Storage (visible only to admins).
Usage overview
The top of the page summarises what the whole instance is holding:
- Database size — total size reported by the database, with the event count.
- Transactions and Spans — performance data row counts (a transaction has many spans, so spans are usually the largest by count).
- Source maps — the on-disk weight of uploaded source-map artifacts and how many files.
Row counts are exact. The database size is the figure the backend reports (pg_database_size on PostgreSQL, page count × page size on SQLite); source-map weight is summed exactly from stored file sizes.
By project
A per-project table breaks the same data down by project: events, transactions, spans, source maps, and an estimated size for each. Empty projects still appear with zeros, so you can see at a glance which project is accumulating the most.
The estimated size is the length of the JSON payloads a project holds across events, transactions, spans, and logs. It is estimated from a sample of each project’s newest rows (spans have no ingest time, so theirs are sampled in no particular order), scaled by how many rows it has, so the page stays fast however much data the instance holds; the row counts next to it are exact.
Cleaning up old data
Under Clean up old data you pick:
- Retention period — older than 7, 30, 60, or 90 days.
- Scope — all projects, or a single project.
Then Preview runs a dry-run: it counts exactly what would be removed and deletes nothing. You see how many events, transactions, spans, and empty issues a cleanup would remove before committing. Confirm in the dialog to delete.
The cleanup then runs in the background on the server. The page shows its progress as it goes, and you can leave it: the cleanup keeps running, and coming back to the page picks it up again. Only one cleanup runs at a time.
What a cleanup does:
- Deletes events and transactions older than the cutoff (a transaction’s spans cascade away with it).
- Removes any issue left with zero events — no empty ghost issues are kept.
- Keeps the denormalized event counts on projects and issues in sync, exactly like deleting an issue does.
- Deletes in small batches, each committed on its own, so it never holds the database for the whole purge and ingestion keeps working while it runs. If the server restarts mid-cleanup, what was already deleted stays deleted; run it again to finish the rest.
Retention is keyed on ingestion time (when Rustrak received the data), not on the client-supplied timestamp, so a bad clock on a sender can’t hide data from cleanup.
Warning: Cleanup permanently deletes data and cannot be undone. Always run the preview first and check the counts.
Orphaned source maps
Source maps are content-addressed and shared, so deleting a project leaves its source-map files behind with nothing referencing them. The Orphaned source maps panel reclaims that space:
- Preview counts the orphaned files and the bytes a cleanup would free — it deletes nothing.
- Remove deletes those files from the database and disk.
It only ever touches files that no upload references — files still used for symbolication are never removed. Chunks from completed uploads are already cleaned up automatically during assembly, so they don’t accumulate.
API access
Every endpoint requires an admin bearer token (or admin session). Non-admins get 403 Forbidden.
# Instance-wide summary
curl -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
http://localhost:8080/api/storage/summary
# Per-project breakdown
curl -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
http://localhost:8080/api/storage/projects
# Dry-run a cleanup (deletes nothing)
curl -X POST -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"older_than_days":30}' \
http://localhost:8080/api/storage/cleanup/preview
# Start the cleanup (optionally scoped to one project). Answers 202 at once.
curl -X POST -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"older_than_days":30,"project_id":1}' \
http://localhost:8080/api/storage/cleanup
# Follow it until it is no longer "running"
curl -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
http://localhost:8080/api/storage/cleanup/status
# Dry-run, then remove, orphaned source maps
curl -X POST -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
http://localhost:8080/api/storage/source-maps/gc/preview
curl -X POST -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
http://localhost:8080/api/storage/source-maps/gcThe preview returns the counts a cleanup would remove:
{ "events": 1240, "transactions": 80000, "spans": 1200000, "logs": 5000, "issues_removed": 37 }Starting a cleanup and asking for its status both return the job. state is idle (none since the server started), running, completed or failed, and removed has the same shape as the preview: the rows deleted so far while it runs, the total once it has finished.
{
"state": "completed",
"removed": { "events": 1240, "transactions": 80000, "spans": 1200000, "logs": 5000, "issues_removed": 37 },
"started_at": "2026-10-07T10:00:00Z",
"finished_at": "2026-10-07T10:04:12Z",
"error": null
}You can also drive all of this from an AI assistant via the MCP server — the destructive cleanup tool requires an explicit confirmation flag before it will run.
Behavior reference
| Situation | Result |
|---|---|
| Member opens Settings → Storage or calls a storage endpoint | 403 Forbidden |
| Preview (cleanup or source-map GC) | Counts only — nothing is deleted |
| Start a cleanup | 202 Accepted; it runs in the background |
| Start a cleanup while one is running | 409 Conflict |
| Server restarts during a cleanup | Batches already deleted stay deleted; run it again for the rest |
| Cleanup scoped to one project | Other projects’ data is never touched |
| Issue left with zero events after cleanup | Issue is deleted |
| Source-map GC | Only unreferenced (orphaned) files are removed |
| Deleting events | Project and issue event counts stay consistent |