Documentation

Backup and Restore

This page is also in the Groundskeeper wiki: https://github.com/rsjsoftwareltd/groundskeeper/wiki/Backup-and-Restore

Groundskeeper keeps everything it needs in a small number of files on the server. Backing up is mostly a matter of copying those somewhere safe; the installer already preserves them across upgrades.

What to back up #

Everything lives under C:\ProgramData\RSJ Software\Groundskeeper\Server (not the install directory -- as of v0.66.0, Groundskeeper's writable data is kept separate from the application binaries in C:\Program Files\RSJ Software\Groundskeeper, so the service account only ever needs write access to the ProgramData folder; as of v0.181.0 that folder sits under the RSJ Software company folder, beside the other RSJ products). The two files that matter are:

Back up both together and you have everything.

Groundskeeper backs the database up for itself (v0.96.92 and later) #

You no longer have to arrange this yourself for groundskeeper.db. Every night, Groundskeeper takes a copy of the database, checks that the copy is readable before keeping it, and deletes the oldest once it has more than it is asked to keep.

Settings -> Backup -> Database Backup shows the schedule, where the files go, and what is there, with a Back up now button if you would rather not wait for tonight.

Defaults, all changeable in config.yaml under backup::

When02:30 daily
Wherea backups folder next to the database
How many kept7

Point directory at another drive or a file share if you can. A backup on the same disk protects you from a corrupted file or a bad change; it does not protect you from that disk failing. The service account needs write access to wherever you choose.

If a backup fails -- no space, no permission, an unreadable copy -- it appears once on the dashboard feed, with the reason, and once more when it starts working again. It will not repeat every night.

Why not just copy the file yourself? #

You can, but stop the service first. Groundskeeper's database runs in SQLite's WAL mode, where a recently-saved change lives in the groundskeeper.db-wal file until it is folded into the main one. Copying groundskeeper.db on its own while the service is running can therefore miss recent data without any sign that anything went wrong -- you get a file that looks fine and quietly restores to an earlier state.

The built-in backup uses SQLite's own backup mechanism, which is safe to run while the service is working and always produces a complete copy.

Your settings are saved beside each copy (v0.113.0 and later) #

Each nightly database copy gets a groundskeeper-<stamp>.config.yaml beside it -- that night's config.yaml, as it was. It lives and dies with its database copy, and the restore dialog can put the two back together (below). Two things to know: the saved credentials in it can only be read on the machine that saved them, so it does not move settings to a new server -- Settings -> Backup -> Backup & Restore still does that, as a password-protected file you can download; and everything else in it is as you typed it (community strings, server names), so a backup folder on a share deserves the same access control as config.yaml itself. include_config: false under backup: turns the copy off.

Restoring one of these backups (v0.102.0 and later) #

Each backup in the list on Settings -> Backup -> Database Backup has a Restore... button. It is deliberately not a quick click:

  1. The confirmation says exactly what is lost -- everything Groundskeeper recorded after that backup was taken (alerts and their acknowledgements, incidents, device check-ins, connector state) -- and you type RESTORE to go on. Your settings and credentials in config.yaml are not touched -- unless you tick Also put back the settings saved with this backup, offered when that night's settings were saved beside it, which restores that config.yaml too and keeps the one it replaced beside it as config.pre-restore-<stamp>.yaml.
  2. Groundskeeper checks the backup is readable before anything is replaced, and refuses if it is not, leaving the live database alone.
  3. It then stops and restarts itself to swap the file in, which takes about a minute; the page reloads on its own when the service is back. (If the automatic restart cannot be scheduled -- the account running the service needs to be a local Administrator for that, the same as the About screen's Restart Service button -- the page says so, and restarting the service yourself from services.msc within 30 minutes applies it instead.)
  4. The database it replaced is kept, beside the live one, as groundskeeper.pre-restore-YYYYMMDD-HHMMSS.db (with any -wal/-shm renamed alongside it). If the restore was a mistake, stop the service, rename that file back to groundskeeper.db (deleting the newer groundskeeper.db, -wal and -shm first), and start the service. Only the most recent such copy is kept.

A restore that is staged but not applied within 30 minutes -- because the restart never happened -- is abandoned rather than applied on some later, unrelated restart, and the dashboard feed says so. The feed also records every restore that was applied, naming the backup it came from.

Restoring onto a different machine is still the manual sequence under Restoring below: the button only knows about the backups on this server.

Still worth having your own copy #

An automatic backup on the server is a floor, not a ceiling. Including C:\ProgramData\RSJ Software\Groundskeeper\Server in your normal server backup regime (Veeam or similar) is still the right thing to do -- it gets the backups off the box, and covers config.yaml at the same time.

Upgrading from a version before v0.181.0? Groundskeeper moves your existing data folder from C:\ProgramData\Groundskeeper\Server to C:\ProgramData\RSJ Software\Groundskeeper\Server automatically the first time the service starts on the new version (and, from a version before v0.66.0, out of the install directory in the same step). You don't need to do anything -- just make sure any existing backup job pointed at the old location gets updated to the new path after upgrading. Nothing is deleted: if a file could not be moved, it stays where it was and the log says so.

One confusing side effect worth knowing about: an install that dates from before v0.66.0 may still have an old config.yaml or groundskeeper.db in its program folder, frozen at the date of that upgrade. They are not the live files -- the app only reads the ProgramData location. From v0.182.0 the program folder itself moves, from C:\Program Files\Groundskeeper to C:\Program Files\RSJ Software\Groundskeeper, and any such stale copies are kept, not deleted, in a program-folder-leftovers folder inside the data folder above. Everything else in the program folder belongs to the product (in particular, certs holds your live HTTPS certificate, which the move carries across -- leave it alone).

The DPAPI caveat -- important if you move servers #

The encrypted secrets in config.yaml are protected using Windows DPAPI, which ties the encryption to the machine they were encrypted on. Two secrets that live in groundskeeper.db are protected the same way: on a Central hub, each paired school's token, and the Aruba Central sign-in. This is a good security property, but it has one consequence:

A config.yaml or groundskeeper.db restored onto a different machine will not be able to decrypt its stored credentials -- the encrypted values are only readable on the original server.

So:

Restoring #

  1. Install the same (or newer) version of Groundskeeper on the target server.
  2. Stop the Groundskeeper service.
  3. Copy your backed-up config.yaml and groundskeeper.db into C:\ProgramData\RSJ Software\Groundskeeper\Server, replacing the fresh ones (create the folder first if it doesn't exist yet -- a fresh install creates it on first service start). If you are restoring one of Groundskeeper's own nightly backups, it will be named groundskeeper-YYYYMMDD-HHMMSS.db -- copy it in and rename it to groundskeeper.db. Delete any groundskeeper.db-wal and groundskeeper.db-shm files sitting beside it before starting the service. They belong to the database you are replacing, and leaving them there can undo the restore.
  4. Start the service.
  5. If you've moved to a new machine, either restore the password-protected backup from Settings -> Backup -> Backup & Restore, or re-save each connector's credentials (see the DPAPI note above).

Upgrades preserve your data automatically #

You don't need to back up specially before an upgrade: running a newer GroundskeeperSetup.exe over an existing install preserves config.yaml, groundskeeper.db and your licence automatically. The installer detects the existing install and shows an "Update" flow rather than a clean install. A backup is still good practice, but the upgrade itself is non-destructive.

Data retention #

Most of what Groundskeeper stores in groundskeeper.db prunes itself automatically on a rolling window (feed history and AI query logs after 90 days, password reset tokens after 7 days, and so on). One exception in the feed: the latest event for a problem that is still open is kept until the problem clears, so a long-running problem never drops off the feed. Two tables are exceptions worth knowing about specifically -- a MAT's Data Protection Officer may well ask "how long do you keep this?", and for these two the honest answer is "until you delete it yourself":

Both tables live inside groundskeeper.db, entirely on your own server (see "What to back up" above) -- Groundskeeper never sends this data anywhere. As the data controller for your own installation, decisions about how long to keep old device records or incidents are yours to make; if your school or trust has its own retention schedule, a periodic manual review of these two tables against it is worth building into your routine.

Suggested routine #

See also #

Last updated: 2026-10-18 (v0.192.10)