Storage and privacy
Vocal Analyzer comes in two versions, and they keep your data in different places:
- The browser version runs entirely in your web browser. Analysis runs on your device, and recordings, results and settings are stored in that browser. There is no server copy.
- The installed app runs a local server on your computer (with
Docker or
uv) that you open in a browser. It stores data in a folder or Docker volume on the machine that runs the server, and also has a command-line tool (CLI).
Neither version has an account system, and neither encrypts stored data itself.
What is stored
A completed analysis is saved as a session so the history, comparisons and reruns keep working after you reload the page. A saved session can include:
- the recording you uploaded or recorded;
- the settings used for that analysis;
- the analysis result, including acoustic measurements, timeline data, transcript data when transcription ran, summaries, evidence status, and chart data;
- the display label and original filename.
Your preferences (goal profile, target bands, display choices, layouts) and practice records are stored as well.
In the browser version
Where it lives
The browser version stores everything in the storage the browser gives to the web address the app was opened from:
- Recordings are files in the browser's Origin Private File System, a private storage area that other sites and ordinary file browsers cannot see.
- Sessions, analysis results, preferences, settings and practice records are in the browser's IndexedDB database. A live take is also written to IndexedDB while you record it, so it can be recovered if the tab closes or crashes.
- The analysis software the app downloads the first time you analyze a recording is kept in the browser's cache storage, so later analyses work without a network connection.
- A few display conveniences, such as the colour theme and whether the sidebar is collapsed, are in the browser's local storage.
Settings → Storage on this device shows how much space the app uses.
Nothing leaves your device
Analysis runs inside the browser. The app downloads its own code and analysis software from the site it was opened from, and the page is not allowed to connect to any other address. It does not send recordings, results, transcripts or settings anywhere.
Storage belongs to one web address
Browser storage belongs to the exact web address (origin) you opened the app from. Sessions saved at one address do not appear at another, and they do not appear in a different browser, a different browser profile, or on another device. Before you switch to another address, browser or device, export a backup and import it there.
The browser can delete your data
There is no server copy of your data. The browser can remove it:
- when you clear the site's data, cookies or browsing history for it;
- when the browsing session ends in a private or incognito window (some browsers, such as Firefox in private browsing, do not allow the app to store data at all);
- when the device runs low on space and the storage is not marked as persistent.
The app asks the browser to keep its storage persistent each time a recording is saved. Settings → Storage on this device shows whether the browser agreed and offers the request again. Even persistent storage is removed if you clear the site's data.
Backups
Settings → Export backup saves every recording with its audio and
results, your preferences, settings and practice records in one .vab
file. Downloaded analysis software is not included; the app downloads it
again when needed. Keep backup files private: they contain your
recordings.
Settings → Import backup adds the sessions from a backup that are not already in this browser. It never replaces data saved here, and it skips sessions you deleted in this browser.
You can also download one session's result as JSON, or its original audio, from the history row.
Live takes
While you record a live take, its audio is written to the browser's storage as it arrives. After Stop, Save to practice log saves the take as a session and deletes the temporary copy; Discard deletes it without saving. If the tab closes or crashes during a take, the app offers the unsaved take the next time it opens, so you can save, download or discard it. Live preview numbers are not saved; the saved result is the full analysis of the recording.
Deleting
Deleting a session removes its record, result and recording from the browser. To remove everything, clear the site's data in your browser's settings; export a backup first if you might want it back.
If the browser's database is lost but recording files remain, Settings lists them under Files without a database entry so you can download or delete them.
In the installed app
Speaker references and model files
Speaker similarity is available only in the installed app. When the
optional WeSpeaker runtime and model are available, a completed web
analysis may also contain speaker-embedding.json in its job directory. This
private, model-versioned sidecar powers the self-similarity trajectory. It is
not included in job, session, or trajectory JSON responses; those endpoints
return derived cosine scores only. Sessions created without the optional model
have no sidecar and otherwise behave normally.
Speaker references are stored separately as enrollment JSON files. An enrollment contains the normalized embedding, model name/version, source path and source sha256 for provenance, and creation timestamp. It does not keep a copy of the source reference audio after enrollment.
Whisper and WeSpeaker model files may also be cached locally when you enable those optional features. Those caches are model artifacts, not recordings or results.
Where it lives
For local make dev-serve or CLI use, jobs, enrollments, and lightweight
practice summaries share the platform data directory reported by
platformdirs.user_data_dir("vocal-analyzer").
On many desktop systems this is a user-scoped application-data folder
such as ~/Library/Application Support/vocal-analyzer on macOS or
~/.local/share/vocal-analyzer on Linux.
Small whole-file stores (config.toml, preferences.json, and practice
summaries) are replaced atomically after their new contents are flushed. An
interrupted save therefore keeps the previous complete file instead of leaving
a partially written document. This protects file integrity; it is not a backup
or a substitute for free disk space and writable storage.
For Docker, the same paths are mapped to persistent volumes. The
important one is vocal-data mounted at /data, which holds completed
web sessions and speaker enrollments. vocal-config stores config and
vocal-cache stores downloaded model files.
Lifecycle and deletion
A completed session remains on disk until you delete it or remove the underlying data directory/volume. The application currently does not apply an automatic age-based retention policy.
A live take recorded on Practice is written to a WAV file on Stop and held until you choose:
- Discard removes the audio; it does not create a saved history entry.
- Save to practice log submits the recording through the same job pipeline as an uploaded file. From that point on, storage and deletion behave like any other completed session.
Preview packets and rolling live metrics are not saved as
AnalysisResult records. The saved report is the final batch analysis,
not the transient live display.
In the dashboard, deleting a saved session calls
DELETE /api/v1/sessions/{session_id}. That removes the job record and
its per-job artifacts, including the uploaded audio sidecar, result JSON, and
any private session-embedding sidecar. The session-index entry is removed
first, so a deleted session disappears immediately; if reclaiming the files
themselves transiently fails (for example, a file locked by another program),
a background sweep finishes the cleanup at the next server start or daily
maintenance run.
Speaker enrollments can be removed with the web/API reference delete endpoint or by deleting the enrollment JSON from the local data directory. Deleting an enrollment removes the embedding metadata; it does not delete any completed analysis that previously used that reference.
Docker users can remove all application state with docker compose down -v. That deletes sessions, enrollments, config, and model cache
volumes, so use it only when you really want a reset.
Exporting your data
You can export a completed result from the dashboard history row, or by
saving the JSON returned from GET /api/v1/sessions/{session_id}. The
original uploaded audio for a saved session is available from the
history row's audio download action or from
GET /api/v1/sessions/{session_id}/audio. There is no one-click bulk
export in the dashboard yet.
CLI output formats (--format json, --format md, and --format html)
write analysis results wherever you choose. Those exported files are
separate from the dashboard history and are not removed when a web
session is deleted.
Remote deployment risks
The default Docker Compose port is bound to 127.0.0.1, so the service
is intended for local use. If you expose it to a LAN or the internet,
you are responsible for the missing production controls: authentication,
TLS termination, authorization, rate limiting, disk quotas, backups, and
host-level encryption-at-rest if you need it.
Do not expose the app directly on a public network. Put it behind an authenticating reverse proxy and treat uploaded recordings, result JSON, transcripts, and speaker embeddings as sensitive local data.
Deferred improvements
The storage lifecycle is explicit, but a few privacy affordances remain future work:
- configurable automatic retention, such as deleting sessions older than a chosen age or keeping only the most recent N sessions;
- bulk export and bulk delete for dashboard history;
- clearer disk-usage reporting for saved sessions and model caches;
- explicit OpenAPI response annotations for structured non-2xx errors, including upload limits, missing sessions, duplicate references, and unavailable neural dependencies.
These are intentionally deferred rather than implied by the current local-first implementation.