DB backup
Speechwave runs on SQLite, and in production, Speechwave.DbBackup keeps that database backed up on a schedule. It’s a GenServer, and it only starts when the right storage configuration is present, which means it never runs in local development.
The schedule
After boot, the first backup runs a short time later, and then on a repeating hourly interval after that.
@initial_delay :timer.minutes(5) @interval :timer.hours(1)
How the snapshot gets taken
The backup uses SQLite’s VACUUM INTO to produce the snapshot.
A plain file copy of a live SQLite database can catch it mid-write and produce a corrupt snapshot. VACUUM INTO produces a consistent, compacted copy without locking the database or causing any downtime, which makes it a much safer way to snapshot a database that's actively being written to.
Once the snapshot file is written, it gets uploaded to S3-compatible object storage using a signed upload. The temporary file is always deleted afterward, whether or not the upload succeeded, so a failed upload doesn’t leave anything behind on disk.
Failures are caught and logged. A failed backup doesn’t crash the GenServer or affect the running database in any way, it just means that cycle’s snapshot didn’t make it to storage. See Supervision tree for what happens if the process itself crashes.
Manual trigger
run_now/0 is exposed so a backup can be triggered on demand from IEx or a Mix task, without waiting for the timer.
Speechwave.DbBackup.run_now()