The daemon redacts before serialisation; the cloud cannot see what the daemon never sends.
The daemon’s [cloud.upload] config block governs every field of every
captured request before it touches the wire. The defaults are intentionally
conservative: the daemon syncs the metadata that lets the cloud roll
spend up and reconcile, and does not sync the high-leak fields by
default (local filesystem paths, captured request and response bodies).
You can broaden or narrow the policy globally (preset), per-field
(fields.*), or per-project (per_project.[slug]). Per-project rules
override the global preset.
Tiered presets
Three presets ship in the daemon. The default for v0.2.0+ is standard.
| Preset | Method, provider, model, tokens | Cost | Project slug | Hostname | Prompt hash | Workdir path | Bodies |
|---|---|---|---|---|---|---|---|
minimal | ✓ | ✓ | ✓ | – | – | – | – |
standard (default) | ✓ | ✓ | ✓ | ✓ | ✓ | – | – |
full | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – |
Bodies are never on by default at any preset; opt them in separately (see Body sync below).
Switch preset with:
$ halton-meter cloud privacy set preset standard
$ halton-meter cloud privacy show
● Preset: standard
● source_workdir: false
● prompt_hash: true
● hostname: true
● Body sync: disabled
● Per-project rules: 2 active (personal, side-project) Synced fields (standard preset)
What the cloud sees per row, with the default standard preset:
| Field | What it is | Why it syncs |
|---|---|---|
request_id | UUID v4 generated by the daemon | Primary key on cloud side; reconciles back to the local row |
timestamp | ISO-8601 with timezone | Charting, retention windows |
provider | anthropic / openai / gemini / xai | Group-by in rollups |
model | e.g. claude-sonnet-4-6 | Group-by in optimisation |
method, path | HTTP method and route | Disambiguates messages vs. embeddings vs. files |
status_code | HTTP status | Error rate, retry analysis |
prompt_tokens, completion_tokens, cache_read_tokens, cache_write_tokens | Token counts from the provider’s wire response | Cost recompute, reconciliation |
cost_usd_millicents | Daemon-computed cost in 1/1000 of a cent | What you logged (the left side of reconciliation) |
provider_request_id | Provider’s own request ID | Links to provider’s billing line items in reconciliation |
project_id | Project slug from Smart Attribution | Group-by in every dashboard |
attribution_method | Which resolver tier won (e.g. rcfile, parent_ide_argv_label) | Lets you audit attribution quality |
hostname | Machine hostname (only on standard/full) | Device-level filters in the dashboard |
prompt_hash | SHA-256 of the prompt, truncated to 16 hex chars | Dedup detection without seeing the prompt |
Excluded fields (default)
Off by default at every preset, opt in explicitly per field:
source_workdir— the absolute filesystem path the request originated from (/Users/vk/code/acme-api). Opt-in viacloud privacy set field.source_workdir true. Some teams want this for forensic reasons; most should leave it off.request_bodyandresponse_body— the full JSON of the request to the provider and the response. See Body sync below.
Fields the daemon never sends:
- Raw
Authorizationheaders (the daemon strips them at capture time before they ever land in SQLite — they are not in the local store either). - Other request headers beyond
User-AgentandContent-Type. - TLS material, including the daemon’s local mitm CA.
Body sync
Body sync (the full request and response JSON) ships from v0.2.2 and is off by default. Opt in with:
$ halton-meter cloud privacy set bodies.enabled true
● Bodies will now upload on the next sync cycle.
● Cap: 524288 bytes per direction; oversized bodies are skipped. The [cloud.bodies] block:
[cloud.bodies]
enabled = false # master switch; default false
sync_interval_seconds = 60 # how often the BodyUploader drains
max_body_bytes_per_upload = 524288 # 512 KiB cap per direction
Per-project override drops body uploads for a single project while leaving the global switch on:
$ halton-meter cloud privacy set bodies.upload false --project acme-secret
● Project 'acme-secret' will not upload request/response bodies.
● Metadata uploads continue per the global preset. Bodies are stored cloud-side keyed on request_id (one row per
request, with redaction_applied OR-merged across the two POSTs).
Direction is tagged request or response. Retention follows the
same per-tier window as metadata.
Retention windows
Cloud-side retention is per-tier and starts at the row’s sync timestamp.
| Tier | Metadata retention | Body retention |
|---|---|---|
| Solo | 90 days | 30 days |
| Team | 13 months | 13 months |
| Business+ | 24 months | 24 months |
| Enterprise (on-prem) | Configurable | Configurable |
When a row exceeds its retention window the cloud-side daemon deletes
it. The local SQLite store is untouched — your daemon retains every
row indefinitely until you halton-meter prune or wipe the store.
Export your data before it ages out: every project’s PDF report and the audit-log CSV are downloadable from the dashboard.
Opting out per project
Marking a project as local-only:
[cloud.upload.per_project."acme-secret"]
upload = false
Or via the CLI:
halton-meter cloud privacy set upload false --project acme-secret
When a project is local-only, the daemon’s metadata uploader skips
every row tagged with that slug, the body uploader skips both
directions, and the cloud’s projects list will not see the slug appear.
The local capture continues exactly as before — halton-meter report
still shows the cost.
This is the right choice for:
- Personal terminal usage that has no business on a team dashboard.
- Client engagements with strict data-handling clauses.
- Sensitive prototypes that you do not want surfacing in optimisation recommendations.
Disconnecting
Disconnecting (halton-meter cloud disconnect) revokes the token and
wipes local credentials but does not delete the cloud-side data.
Re-connect from the same machine within the retention window and the
existing rows reappear in the dashboard.
To delete cloud-side data for a workspace, delete the workspace from
app.haltonmeter.com/[workspace]/settings. The 30-day grace period
gives you time to export.
See also
- Cloud overview — what the hosted cloud adds
- Connect your meter — pair the daemon first
- Cloud security — encryption, access, audit
- Workspaces — per-workspace billing and members
- SQLite schema — the local shape Cloud reads a subset of
- Local-only guarantee — the daemon’s local-only contract