Backups, retention and upgrades
Back up D1, Postgres and SQLite, export data as JSON or CSV, purge old data, and upgrade Analytik safely.
Backups
Analytics data is easy to lose and impossible to recreate, so back it up like any other database.
D1
npx wrangler d1 export analytik --remote --output backup-$(date +%F).sql
A D1 export blocks queries on that database while it runs, so do it at a quiet hour. D1 also has Time Travel, which restores the database to any minute within a retention window that depends on your plan; see Cloudflare’s documentation for the current window.
Postgres
pg_dump --format=custom "$DATABASE_URL" --file "analytik-$(date +%F).dump"
Supabase and Railway also take their own backups on paid plans. Check what yours includes.
SQLite
Do not copy the file while the server is writing. Use SQLite’s online backup, which is safe with the server running:
sqlite3 /data/analytik.db ".backup '/backups/analytik-$(date +%F).db'"
For continuous replication to object storage, run Litestream next to the process.
Portable export
GET /api/sites/SITE_ID/export?format=json (or csv) returns all the data for one site, as admin. It is the format to use for moving between storage backends or leaving Analytik, and it is not a replacement for database backups.
curl -b cookies.txt "https://analytics.example.com/api/sites/SITE_ID/export?format=json" -o site.json
Retention
Data is kept until it is deleted. Each site has a retentionDays setting (a whole number of days, or empty to keep everything). When it is set, Analytik purges older data by itself: the ingest path checks it at most once an hour per server instance, so there is no cron job to set up. You can also purge by hand, for one site and any date, with the purge route:
curl -b cookies.txt -X DELETE \
"https://analytics.example.com/api/sites/SITE_ID/data?before=2025-01-01"
before is an ISO 8601 date or Unix milliseconds. The purge, automatic or manual, removes:
- events and sessions older than the date;
- payment claims (the payment ids seen on return pages) older than the date;
- visitors that are left without any session.
Payments are not deleted, because the revenue numbers depend on them. Payments older than the date keep their amount, currency, provider and dates, but their email, name, customer id, visitor id and session id are cleared. Such a payment still counts in revenue and no longer points at a person or a source.
Deleting data you no longer need is also the best way to stay inside the storage limit of a free plan.
Strict-mode salts are handled separately and automatically, whatever retention you set. The first request that arrives in a new month creates that month’s salt and deletes the older ones, so a salt is removed from the live database once the next month starts to see traffic.
Backups and retention
Retention and salt deletion apply to the live database only. A backup, a Time Travel restore point or a Postgres point-in-time recovery window still holds the data and the salts as they were when it was taken. If you promise visitors that old data is gone, keep backups only as long as you keep the data itself: set a retention period for your backups that matches retentionDays, and delete old dumps.
Updating
The dashboard tells you when a newer release is out: a bar above the header says “Analytik 1.2.0 is available” and links to what’s new and to this page. Closing it hides that version for every admin; the next release shows it again. The server looks the version up on the npm registry at most every six hours (the browser contacts nobody); pass updateCheck: false to createAnalytik() to turn it off.
How to update depends on how you deployed:
- Created with
npx analytik create: from the project folder, runnpx analytik upgrade(ornpm run analytik:upgrade; new projects have that script, and for an older one add"analytik:upgrade": "analytik upgrade"to itspackage.jsonscripts, usingyarn run analytik:upgradewith Yarn; it is not calledupgradebecausebun upgradeis a Bun command). It installs the newestanalytikwith the package manager the project uses and, for a Cloudflare project, deploys it and prints the Worker’s size next to Cloudflare’s limit.--no-deployonly updates the package. On Vercel it installs and tells you to deploy withnpx vercel --prodor by pushing. - Created with a deploy button: the template ships a Dependabot config, so GitHub opens a pull request when a new release is out. Merge it and the connected host (Workers Builds, Vercel) redeploys. Without Dependabot, raise the
analytikversion inpackage.jsonand push. - Your own project:
bun add analytik@latest(or the same with npm, pnpm or yarn) and deploy the way you always do.
The database schema updates itself on the first request after a deploy (autoMigrate, on by default), so there is nothing else to run. For a major release, read the changelog first, and see the careful steps below.
Upgrades
Analytik follows semantic versioning, and the changelog lists every change. Migrations are ordered SQL files applied once each and recorded in schema_migrations.
- Read the changelog entries between your version and the new one.
- Take a backup.
- Install the new version:
bun add analytik@latest. - Run the migrations before the new code starts serving traffic:
npx analytik migrate --db "$DATABASE_URL"ornpx analytik migrate --db ./data/analytik.db.storage.migrate()does the same from code and is safe to call repeatedly. D1 cannot be reached from the command line; there the Worker applies pending migrations on its first request (autoMigrate, on by default). To create the schema of a new D1 database yourself, usenpx analytik migrate --print-sql sqlite > analytik-schema.sqlandnpx wrangler d1 execute <db> --remote --file analytik-schema.sql, see the CLI reference. - Copy the new
analytik.jsto where you serve it, if the changelog notes a tracker change. - Deploy.
Plan on migrations moving forward only. To go back to an older version, restore the backup you took in step 2.
Check an installation any time with npx analytik doctor; see the CLI reference.