Backups
Automatic snapshots of your site's code, daily archives of its storage and its database, and what you can do with each.
On this page
Modulify snapshots your site's code as you work, and archives the files in its storage once a day, along with its database on a site on the newer database. There is no save button for code, no naming a code snapshot and no diff view, and going back is the only thing you do with one. A storage or database archive is different: you can take one by hand, download it, delete it and turn the daily one off for a site. A storage archive can also be browsed and restored, in whole or in part, while a database archive cannot be restored. Chat and a connected AI client can do all of that except download one: they browse a storage archive, read a text file out of it and restore it once they have shown you what the restore would change and you have said yes, as Backups from chat and MCP describes.
Open the history
The Backups tab lives behind More in the tab strip. Click More, then Backups in the list on the left.
Inside it sit three tabs. Code is the history of your site's files, Storage is the history of the files in your Storage bucket, and Database is the history of your site database. They are separate because they are backed up in different ways: code is snapshotted as you build, while storage and the database are archived once a day. While Storage or Database is open, Backup sits at the right end of that same strip. It never appears on Code.
The Storage tab also opens from the Storage panel. Its Configuration sub-tab has a Backups section, and its View backups button lands straight on this tab, on the free plan too. The same section holds the Daily backups switch, and the Danger zone below it holds Delete all storage backups.
The Database tab opens from the CMS the same way. Its Settings sub-tab has a Backups section between Export and Danger zone, and its View backups button lands straight on the Database tab, on the free plan too. On a site on the older database that button is greyed out, and hovering it reads Backups need a site on the newer database. That section holds the database Daily backups switch, and the Danger zone below it holds Delete all database backups.
Before anything has been recorded, the Code panel reads No code backups with Code backups appear here as you build. If the history cannot be loaded you get Could not load code backups and Refresh the page to try again.
What creates a backup
A snapshot is taken automatically when:
- a chat message finishes and it changed files
- a batch of inline text edits is applied
- you restore an older backup
- changes still only in the preview are saved on their own, for example after a chat message is stopped or fails, when the editor opens again, or just before a publish
- your code is moved to your own GitHub, which records the point it moved
Apart from the point your code moves to your own GitHub, a snapshot is only taken when files actually changed. A chat message, a publish, a text edit or a restore that leaves your files exactly as they were does not create one.
Read an entry
Each row reads v12 by Sam, where the number counts up from the oldest snapshot, followed by a badge, the time it was taken, and the first seven characters of its commit.
The badge is Restore for a backup created by restoring, Text edit for a batch of inline text edits, Preview sync for changes saved from the preview on their own, Repository move for the point your code moved to your own GitHub, and Automatic for everything else. The list loads ten at a time and fetches more as you scroll.
Restore a backup
Open the three dots menu on a row and choose Restore.
Restoring puts every file back to how it was at that point, then reloads the preview against them. It also does two things that are easy to miss:
- The chat transcript is deleted for everyone in the project. The conversation does not survive a restore.
- Anything queued in chat is thrown away unsent.
Because of that you are asked to confirm whenever there is something to lose. If messages are queued the dialog reads Restore this code backup? and warns that restoring erases the chat transcript for everyone. If AI is generating right now, it reads Stop AI and restore this code backup?, the button says Stop and restore, and it stops the job and discards the changes it had not finished. With nothing queued and nothing running, the restore happens straight away.
When it lands you get a Code backup restored toast. Everyone else in the project sees the restore happen too.
Everyone with the File Explorer open sees the restored code as soon as the restore lands: open files reload with the restored version, and files the backup does not contain leave the tree and their tabs close. While a restore runs, restoring again answers Another code backup is already being restored for this site!, an inline text edit shows Could not save text with A code backup is being restored. Try your edit again when it finishes!, and a publish waits for the restore to finish. A restore started while a save is still running, such as the files of a chat message that just finished, waits for that save first. If the save is still running after 30 seconds, nothing is restored, the chat is left as it was, and the restore answers Your latest changes are still being saved. Try restoring again in a moment!
If the preview cannot be reloaded with the restored code, it shows Could not load your files with a Retry next to it, and nothing from the preview is saved until it reloads. Your restored code is already saved, so pressing Retry only reloads the preview. Once anyone reloads it successfully, the message clears for everyone in the project.
Restoring does not publish. Your live site keeps serving whatever you published last until you publish again.
Storage backups
The Storage tab is a separate history, for the files you and your site put in storage. It is a paid feature.
On any paid plan, a daily run archives every site without you asking, unless daily backups were turned off for that site. The run has fifteen minutes. If it cannot get through every site in that time, the rest move to the next daily run, which starts with the sites that have waited longest, and a site whose archive is still being written when the time is up keeps archiving in the background and is not started again the next day while that archive is still running. The daily run archives one site at a time and leaves the second of the two platform archive slots free, so a backup you ask for yourself never waits behind it. The archive is a single .zip of everything in the bucket at that moment, public and private files alike, and it is kept away from your storage so it never counts against what you are using.
Archives are private. They are never served from your storage CDN address or any other public link, and the only ways to see inside one are Browse files and Download, both described below.
A day where nothing in your storage changed is skipped rather than archived again, so a quiet site does not fill the list with identical copies. Adding, replacing or deleting a file is enough to make the next daily archive run.
Read an entry
Each row starts with who took it, the way a code backup does. A backup someone took by hand starts with that person's avatar and is titled with their first name, for example Backup by Sam, or Manual Backup when their name is not known. A daily archive starts with a calendar icon and is titled Daily Backup. The backup a restore takes of your storage before changing it starts with the avatar of the person who started the restore and is titled Before restore. A backup taken through chat or a connected AI client with a name of its own shows that name as its title instead.
The line under the title always starts with a type badge, Manual for a backup someone asked for, Daily for the automatic archive and Before restore for the backup a restore took first, followed by the date and time it was taken, how many files it holds and how big the archive is. Dates and times on a row read in your own timezone. The list loads ten at a time and fetches more as you scroll.
While an archive is being built a second badge, Archiving, sits next to the type badge, and the file count and size are left off, because they are not known until it finishes. Once the files have been counted, the line shows how far the archive has got after the date: a percentage and the bytes written so far out of the total, for example 42% · 1.2 GB of 2.9 GB. It moves on its own, for everyone with the editor open, so a large storage can be watched from any seat. If it could not be built that second badge reads Failed, the file count and size stay off, and a small info icon sits right after Failed. Hover or focus the icon to read the reason; it is not written out on the row itself. The type badge never goes away, so a failed manual backup still reads Manual beside Failed.
Backup
Backup sits at the right end of the tab strip while the Storage tab is open. Choosing it asks Back up your storage now? first. The dialog says every file in your storage is archived into a backup you can browse, restore or download later and that your live files are untouched, then tells you what the backup costs from your allowance, for example This uses one of your 10 manual backups in the last 24 hours, so 6 will be left. When only one is left it reads This uses the last of your 10 manual backups, and the next one unlocks once your oldest one is a day old.
Confirm with Back up now. The row appears straight away as Archiving, shows its progress once the files are being read, and fills in once the zip is built, so a large bucket does not leave you waiting on the button. Only one backup of a site runs at a time, so asking for another while one is still being built is refused with A backup of this storage is already running!
The row appearing is not the files being read. Two archives are built at a time across the whole platform, so a backup can sit in line before it starts listing your bucket, and while a very large archive of another site is being built that wait can run to hours, with the row reading Archiving and no progress on it yet. What the backup holds is your storage as it stands at the moment the files are read rather than at the moment you pressed the button. If you are backing up before a clear out, wait for the row to read its file count and size before you delete, move or change the visibility of anything, because a file that left in between is simply not in the zip.
You get ten manual backups per site in any twenty four hours. The button is disabled once they are spent, and hovering it reads You have used all 10 manual backups in the last 24 hours. A backup that fails does not spend one. Deleting a manual backup does not give its slot back either: it keeps counting against the ten until twenty four hours after it was taken, so the allowance only refills as that time passes.
On a free workspace the button is disabled with a Paid badge beside it, and hovering it reads Backing up your storage requires a paid plan. If your plan cannot be confirmed, it is disabled with We could not confirm your plan, so backups are unavailable right now. and no badge. The button is greyed out with no tooltip while the list is still loading, and if the list could not be loaded it stays greyed out with Backups could not be loaded, so a new one cannot start yet. It also waits with Wait for the backups to finish deleting. while Delete backups is still running for this site. While a restore of this site's storage is running, it waits with Wait for the restore to finish before taking a backup.
A backup needs something to archive, and it has to fit in one archive. Backup on an empty bucket leaves a Failed row reading There are no files in your storage to back up!, while the daily archive passes an empty site over quietly. The zip is written out in pieces while the files are read, never assembled whole first, so a large storage backs up the way a small one does and the limits are far off. A bucket holding more than 4 TB of files, measured before they are zipped, leaves a Failed row reading Your storage holds more than 4 TB of files, more than one backup archive can hold!, and one holding more than 100,000 files and folders reads Your storage holds more than 100000 files and folders, more than one backup archive can hold! Both are refused outright rather than archived in part.
If an archive stops before it finishes, for example because the server restarted, it is marked Failed with The backup stopped before it finished! once it has sent no progress for 30 minutes, by the next backup of that site or simply by opening the tab again, and the daily cleanup removes it once a day has passed since it started, so it never blocks new backups for long. That rule is about silence, not length: an archive that keeps reporting progress is left to finish.
Turn daily storage backups off
Daily storage backups are on for every site, including sites created before the switch existed. To stop them for one site, open the Storage tab, switch to Configuration, and turn off Daily backups in the Backups section. The row reads Archive your storage every night. Turning this off stops only the nightly backup, so manual backups still work and existing archives stay. The switch flips at once and you get a Daily backups off toast.
Off means the daily run skips this site's storage and nothing else. Backup keeps working, every archive already taken stays listed and can still be browsed, restored, downloaded and deleted, and archives keep ageing out on the schedule below. The site's database backups have a switch of their own and carry on as they were.
While daily backups are off, the Storage tab of Backups shows one line above the list, Daily backups are off for this site., followed by Turn them back on in Storage configuration., which takes you straight to the switch. Turn it back on and you get Daily backups on, and the next daily run picks the site up again.
On a free workspace the switch is disabled with a Paid badge, because there is no daily run to turn off, and the line above the list is not shown. Any member of the workspace can flip the switch.
Browse a storage backup
Open the three dots menu on a finished row and choose Browse files, or click the row. The backup opens in place of the list and reads like the file browser in the Storage panel: folders first, then files, with Name, Type, Size and Modified columns, a breadcrumb trail along the top and a row that takes you up one folder. A private file shows a lock after its name, and a folder shows a grey lock when its default is private and an amber one when it holds files on the other side of its default, exactly as the Storage panel does. A folder's Size is the total of the files under it, and its Modified is when the newest of them last changed.
The trail starts with Backups, which leaves the backup and takes you back to the list, then Files for the top of the backup, then each folder you have opened. At the other end of the same row sits Read only, and hovering it reads These are the files as they were when the backup was taken. Restore them to change your storage.
Browsing never changes your storage. There is no upload, no drag and drop, no New folder, and nothing to rename, move, delete or make public or private. The index file __modulify-backup.json is not listed.
Browse files stays greyed out until a row is finished. On a row still being archived, hovering it reads Wait for the backup to finish before browsing it., and on a row that failed This backup has no archive to browse.
The backup and the folder you are in are part of the page address, under /backups/storage/. A refresh keeps you where you were, a link to it opens the same folder for anyone in the workspace, and the browser's back button walks you back out of folders and then to the list. The Backups crumb gets you there in one click from wherever you are, which is how you leave a backup opened from a link in a fresh tab, where the back button has nowhere to go.
The search box searches the whole backup, not just the folder you are in, for files whose path contains what you type, ignoring upper and lower case, and lists every match with its full path. Entries load 100 at a time, and if the next ones cannot be loaded you get Could not load more files.
While you are in a folder, every file in it is checked against your storage as it is now. Changed means your storage has a file at that path with a different size, and Missing means your storage has no file at that path. A file of the same size shows no badge, even if its contents changed since or it was made public or private since, and folders and search results never show one. If your current storage cannot be read, or that folder now holds more than 5,000 public or 5,000 private files and folders directly inside it, the badges are simply left off.
If a backup cannot be opened, the view reads Could not load backup with one of these: This backup may have been deleted. when the row is gone, The archive of this backup is gone. when its archive is no longer there, Download this backup to see its files. for a backup in an older format or one whose archive cannot be read, and Check your connection and try again. for anything else. An empty folder reads No files with This folder was empty in the backup., a folder address that is not in the backup reads No such folder with This folder is not in the backup., and a search with no match reads No matching files with Try another name or clear the search.
Preview and download single files
Choose View file from a file's menu to open it in a preview without downloading the archive. The dialog is titled with the file's name and holds the preview, with Download file and Restore file under it.
| Kind | Extensions | Shown as |
|---|---|---|
| Image | png, jpg, jpeg, gif, webp, svg, avif, bmp, ico |
The image |
| Video | mp4, webm, mov |
A player |
| Audio | mp3, wav, ogg |
A player |
pdf |
The document | |
| Text | txt, md, csv, json, xml, html, htm, css, js, mjs, ts, tsx, jsx, yml, yaml, toml, ini, log, sql, vtt, srt |
Plain text |
A text file shows its first 256 KB, with Only the first 256 KB of this file is shown. Download it to see the rest. under it, and an HTML file shows its source rather than the page it would render. A text file larger than 5 MB, or an image, video, audio file or PDF larger than 25 MB, is not previewed and reads No preview with This file is too large to preview., and a file of any other kind reads No preview with Download the file to open it. If the preview cannot be fetched it reads Could not load file with Check your connection and try again.
Download file, in the preview or in a file's menu, saves that one file under its own name without downloading the whole archive. If it fails you get Could not download file with the reason.
Browsing, previewing and downloading single files work on every plan, for every member of the workspace.
Download a backup
Open the three dots menu on a row and choose Download. The archive downloads as a .zip named after your site and the moment it was taken, in UTC, for example my-site-storage-2026-03-04-05-06-07.zip. The row shows that moment in your own timezone, so the hour in the filename can differ from the hour on the row. Open it with whatever unzips files on your computer.
It is a standard zip that stores your files without compressing them, so it is about as big as the files themselves. An archive over 4 GB, or one holding about 65,000 files, uses the ZIP64 form of the format. The index counts as one of those entries, so the switch happens at 65,535 entries in total. The archive tools built into current macOS, Windows and Linux open it, while a very old unzip from before ZIP64 cannot open one of those, so update the tool rather than the archive. Whenever Modulify reads a whole file out of an archive, when you restore it or download that one file, it checks the file's checksum against the one recorded in the zip. A text preview that stops at the first part of a large file is not checked, because only part of the file was read.
Download stays greyed out until a row is finished. On a row still being archived, hovering it reads Wait for the backup to finish before downloading it., and on a row that failed This backup has no archive to download., because neither has a zip to hand you. If the archive behind a finished row is gone, you are told The archive of this backup is no longer available! instead of getting a broken file.
The download goes through a signed link that stops working 15 minutes after you click Download, so a link copied out of your browser does not stay usable.
Inside the zip your files are split by visibility, so you can tell which side each file came from:
public/holds your public filesprivate/holds your private files
Each file keeps the path it had in storage below that folder, so images/logo.png on the public side is public/images/logo.png in the zip.
Alongside the two folders sits one extra file, __modulify-backup.json. That is an index Modulify writes: when the archive was taken, the default visibility of the top level, every file with its path in the zip, its path in storage, its visibility, its size and the time it last changed, and every folder that has its own default visibility. Empty folders are not in the zip itself, so the index is where a folder default is kept. Your own files always sit inside public/ or private/, so a file of yours with the same name never replaces the index. Leave it out when you upload the files again.
To look through a backup without downloading the whole archive, use Browse files instead.
Restore a storage backup
A storage backup can put your files back in two ways.
- Restore backup puts back the whole backup. It sits in a row's three dots menu and at the top of the browse view. Afterwards your storage matches the backup exactly: every file in the backup is written back as public or private, the way it was, every folder default the backup recorded comes back, every file and folder in your storage that is not in the backup is deleted, and the top level default goes back to the one the backup recorded.
- Restore file, Restore folder and Restore selected put back part of it. They sit in the browse view: Restore file in a file's menu and in its preview, Restore folder in a folder's menu, and Restore selected in the bar that appears once you select files and folders. Only the chosen files, and every file under a chosen folder, are written back, along with the folder defaults the backup recorded under those folders. Nothing else in your storage is touched, and the only thing deleted is the other copy of a restored file that has since been made public or private. You can select up to 200 files and folders at once, and selecting more greys out Restore selected with
Select at most 200 files and folders to restore.
Before anything happens, Modulify works out what the restore would change and asks you to confirm with those numbers. Restoring a whole backup asks Restore this storage backup?, for example Your storage will match this backup exactly: 3 files added back, 12 files overwritten and 2 files deleted. A backup of your current storage is taken first, so you can go back., and restores on Restore backup. Restoring one file asks Restore this file? and restores on Restore file. Anything else asks Restore the selected files?, for example The selected files are written back from this backup: 4 files added back. Nothing else in your storage changes., and restores on Restore files. A file that already has the same size in your storage still counts as overwritten, because the same size does not prove the same contents. If the numbers cannot be worked out you get Could not plan restore with the reason, such as Your storage holds more than 100000 files and folders, too many to restore over in one go!
The restore actions are greyed out rather than hidden when a restore cannot start, and hovering one names the reason: Wait for the backup to finish before restoring it. on a row still being archived, This backup has no archive to restore. on a row that failed, You are not allowed to restore storage backups. without the Delete projects permission, Restoring a storage backup requires a paid plan. on a free workspace, We could not confirm your plan, so restores are unavailable right now. when your plan cannot be confirmed, and Wait for the restore that is running to finish. while another restore runs.
Confirming starts the restore, and you get Restore started with Your storage is being restored and its progress shows in Backups until it finishes. It runs in the background, so you can keep working, open another tab or close the editor. Its progress shows in the Storage tab of Backups by the step it is on, skipping the steps it does not need: Waiting to start, Checking your storage, Backing up current storage, Writing files back, Removing extra files and Finishing up. The restore works out what to change again when it starts, so the numbers can differ from the dialog if your storage changed in between.
Files are copied back one at a time straight out of the archive, without the whole archive being read first, and they are always written back before anything is deleted, so your storage is never left empty part way through. If any file cannot be written back, nothing is deleted and the restore fails with Some files could not be written back, so nothing was removed. Run the restore again! If every file was written back but some files that are not in the backup could not be deleted, it fails with Every file was written back, but some files that are not in the backup could not be removed. Run the restore again! Running the same restore again is safe, and it finishes what the first run left.
When it finishes you get Storage restored with Your storage now matches the backup. What it replaced is kept in the Before restore backup., or Files restored with The selected files are back. What they replaced is kept in the Before restore backup. when you restored part of a backup. When no Before restore backup was needed they read Your storage now matches the backup. and The selected files are back from the backup. A restore that fails shows Restore failed with the reason. Those toasts reach the person who started the restore, in an editor that was open while it ran; a teammate watching sees the progress and its finished state but no toast. An open Storage panel refreshes on its own to show the restored files.
Your published site reads the same storage, so a restore changes the files it serves straight away, with nothing to publish. That is the opposite of restoring code. Restoring a whole backup clears the CDN cache for all of your storage, and restoring part of one clears it for what was put back, so the next request for a public file gets the restored copy. A storage restore never touches your site's code, its database or its chat.
The Before restore backup
Before a restore overwrites or deletes a single file, Modulify takes a backup of your whole storage as it stands, so the restore can be undone. It is taken only when there is something to lose: a restore that only adds files back, or one into an empty storage, takes none, and the confirmation only mentions it when one will be taken.
It appears in the Storage list like any other backup, titled Before restore with a Before restore badge. It does not use one of your ten manual backups, and it is kept the way a backup you made yourself is: never thinned early, and removed once it passes a year. To undo a restore, restore that backup, or just the files you need from it. That restore takes a Before restore backup of its own first, like any other.
It is a whole storage backup even when you restore a single file, so the size limits on Backup apply to it. It waits its turn for one of the two archive slots with no time limit, and the restore stays on Backing up current storage for as long as that wait takes. The restore fails with A backup of this storage is still being archived. Try the restore again when it finishes!, without changing a file, only when that backup cannot be started at all after about ten seconds of trying, because another backup of the same site is still being archived or its backups are busy. A storage holding more than 4 TB of files, or more than 100,000 files and folders, cannot be backed up at all, so while yours is over either limit a restore that would overwrite or delete anything fails before it changes a file. Whenever this backup starts and then fails, nothing is restored, the restore fails with The backup of your current storage failed, so nothing was restored!, and the Before restore row reads Failed with its own reason.
While a restore runs
Only one restore runs per site. Starting another gives you Could not restore backup with A restore of this storage is already running!, and a restore cannot start while a backup of the same storage is still being archived, which reads A backup of this storage is still being archived. Try the restore again when it finishes!
Until the restore finishes:
- Your storage cannot be changed from Modulify. Uploading, New folder, moving and renaming, deleting files and folders, Clear storage, and making files, folders or the top level public or private are refused with
Your storage is being restored from a backup. Try again when the restore finishes!in the Storage panel, in the image and file fields of the CMS, and from a connected AI client. Chat is refused too, and tells you in its own words to wait for the restore to finish. - No new storage backup starts. Backup is greyed out with
Wait for the restore to finish before taking a backup., a backup asked for through chat or a connected AI client is refused withYour storage is being restored from a backup. Take a new backup when the restore finishes!, and the daily run passes the site over. - The backups it uses stay put. The backup being restored and its Before restore backup keep Delete greyed out with
Wait for the restore to finish before deleting this backup., deleting either one through a connected AI client answersThis backup is being used by a restore that is still running. Delete it when the restore finishes!and chat is refused too, Delete all storage backups answersA restore of this storage is still running, so its backups cannot be deleted yet. Try again when it finishes!, and the daily cleanup leaves both alone.
Your site's own storage calls are not paused, as Limits and side effects of a restore explains.
If a restore stops before it finishes, for example because the server restarted, it stops holding your storage within five minutes and reads as failed with The restore stopped before it finished, so some files may not be back yet. Run it again! Run it again to finish putting the files back.
Limits and side effects of a restore
- Your site keeps writing. Calls your site makes to storage through the HTTP API or its storage helper are not paused while a restore runs. A file your site writes at a path the backup also holds can be replaced by the backup's copy. Restoring a whole backup decides what to delete when it starts, so a file your site adds after that is kept, while a file it rewrites that is not in the backup is still deleted. For a site that writes to storage on its own, restore at a quiet time.
- Content types are worked out again. A backup does not record each file's content type, so a restored file gets the type its extension suggests. Files ending in
.png,.jpg,.jpeg,.gif,.webp,.svg,.avif,.bmp,.ico,.mp4,.webm,.mov,.mp3,.wav,.ogg,.pdf,.json,.txt,.csv,.woff,.woff2,.ttf,.otfor.zipcome back with their usual type. Every other file, such as an.html,.css,.js,.xmlor.mdfile or a file with no extension, comes back asapplication/octet-stream, which a browser downloads instead of showing, even if it was uploaded with a better type. Check such files after a restore, and upload them again if they no longer open. - Modified times change. Every restored file gets the moment of the restore as its last change, so the Modified column shows the restore rather than the time in the backup, and the next daily archive runs because your storage changed.
- Files added since are deleted. Restoring a whole backup deletes every file that is not in it, including CMS uploads under
CMS/, so a page or CMS row that points at a file added after the backup stops loading it. A restored public file is back at its old path and address, so whatever linked it loads it again. - Some files are skipped. A file in the backup whose path storage no longer accepts, such as a path that is too long or a file named after a storage endpoint like
list, is not written back, and whatever sits at that path in your storage now is left as it is. - The size limits of a backup apply. An archive holds at most 4 TB of files and 100,000 files and folders, and restoring a whole backup is refused when your current storage holds more than 100,000 files and folders.
- Older backups cannot be restored. A backup taken in an older format, or one whose archive cannot be read, cannot be browsed or restored. Restoring it is refused with
This backup was taken in an older format that cannot be browsed or restored. Download it instead!orThis backup archive could not be read. Download it instead!
Get files back from a storage backup
The quickest way to recover files is a restore. Open a backup that still holds them with Browse files, look for the Missing and Changed badges, and restore just those files, or the whole backup, as Restore a storage backup describes. The Restore on the Code tab puts back your site's source files without touching storage. Chat and a connected MCP client can do the same recovery in plain words: they browse the backup, name the files that read Missing or Changed and restore them once you have seen the plan and said yes, on the same paid plan and Delete projects permission this tab asks for. Downloading a backup, or a file out of one, stays yours alone.
When a restore is not open to you, because the workspace is on the free plan, you do not have the Delete projects permission, or the backup cannot be browsed, put the files back by hand. Save single files with Download file from Browse files, or download the whole archive and unzip it, then upload the files you need again from the Storage panel. The panel uploads files, not folders, so recreate a folder with New folder first and drop its files into it.
An uploaded file follows the default of the folder it lands in, not the side it was on in the archive, and the top level default is private unless you changed it from the Top level menu. Check the lock on every file you put back: use Make public on any file from public/ that landed private, and Make private on any file from private/ that landed public. A public file back at the path it had gets the address it had, so pages and CMS rows that linked it load it again.
Who can use backups
A backup holds your private files, so it is guarded like them. Every member of the workspace that owns the site can list and download its backups, browse one, preview its files and download them one at a time, exactly as they can open any file in its storage, and none of that needs a paid plan. Starting a backup needs the workspace to be on a paid plan. Restoring one needs both a paid plan and the Delete projects permission, because a restore can delete files and takes a backup first, so a member without the permission sees the restore actions greyed out with a tooltip rather than missing. A restore asked for in chat or through a connected AI client meets the same two gates: without the permission it is refused and you are told someone who has it has to do it, and on the free plan it answers Restoring a storage backup requires a paid plan! Deleting a backup needs the Delete projects permission too, so a member without it sees a row's Delete and the Delete backups button in the Danger zone greyed out with a tooltip rather than missing. Turning daily backups on or off needs only membership of the workspace. Anyone outside the workspace is turned away before Modulify even looks the backup up. See Members and roles.
Delete a backup
Open the three dots menu on a row and choose Delete. It asks Delete this storage backup? and warns that the archive is removed for good. A row still being built keeps its Delete greyed out, and hovering it reads Wait for the backup to finish before deleting it., because its archive is still being written, so delete it once it has finished or failed. If an archive cannot be reached it stays in the list rather than disappearing from it, and Delete on that row says Something went wrong while deleting your storage backup! If the row was already removed by someone else, by chat, by a connected AI client or by the daily cleanup, you get Nothing to delete with This archive was already gone, so the list is up to date. and the row leaves the list. While a restore is running, the backup it restores and its Before restore backup keep Delete greyed out with Wait for the restore to finish before deleting this backup.
There is no delete all button in the list. To clear the whole history at once, open the Storage tab, switch to Configuration, and press Delete backups on the Delete all storage backups row under Danger zone. It asks Delete every storage backup?, warns that every finished archive for the site is removed for good while a backup still being archived is kept, and deletes on Delete all. You get Backups deleted when it is done, Nothing to delete when the site held no finished archive, and Some backups are still there when some archives could not be reached, which names how many of them are still in the list. The button works on the free plan too, so archives taken while on a paid plan can still be cleared, and it waits with a tooltip while the backups of another site are still being deleted. While a restore of the site's storage is running, it answers A restore of this storage is still running, so its backups cannot be deleted yet. Try again when it finishes!
Deleting a backup removes the archive for good. The files in your live storage are untouched, but that snapshot of them cannot be browsed, restored or downloaded again.
How long they are kept
Archives are thinned as they age, so a year of daily backups never grows without limit:
- every daily archive from the last week
- one archive a week back to eight weeks ago
- one archive a month back to a year ago
Anything older than a year is removed, and backups you made yourself are never thinned early, only removed once they pass a year, and the same goes for Before restore backups. The one archive this thinning never removes is the newest finished one of a site, however old it gets, so a site you stop changing keeps its last archive instead of ending up with none. While a restore runs, the cleanup also leaves alone the backup it restores and its Before restore backup.
A backup that failed is the exception to all of that. It is cleared from the list by the first daily cleanup after a day has passed since it was attempted, whichever kind it was, so read the reason under its info icon while it is there.
When the plan changes
Backups are a paid feature, so going from a paid plan to Free stops new ones. The daily run passes the site over, Backup is disabled with a Paid badge beside it in the tab strip, and the Daily backups switch in Storage configuration is disabled with a Paid badge of its own. Restoring stops too: Restore backup, Restore file, Restore folder and Restore selected are greyed out with Restoring a storage backup requires a paid plan.
The archives already taken are not deleted. You can still browse, preview, download and delete them, and they keep ageing out on the same schedule. Go back to a paid plan and the next daily run picks the site up again, unless daily backups were turned off for it, and restoring works again.
Database backups
The Database tab is a third history, for the tables and rows in your site database. It is a paid feature, and it covers sites on the newer database only.
On any paid plan, a daily run backs up the database of every site on the newer database without you asking, unless daily backups were turned off for that site. It starts early in the morning, UTC. If one run cannot get through every site in time, the rest move to the next daily run, which starts with the sites that have waited longest. The backup is a single .zip holding the whole database as it was at one moment: every table and every row, along with its indexes, triggers and views. It is kept away from your storage, so it never counts against what you are using.
Backups are private. They are never served from your storage CDN address or any other public link, and the only way to get one is the Download action described below.
A day where nothing in your database changed is skipped rather than backed up again, so a quiet site does not fill the list with identical copies. Any write to the database is enough to make the next daily backup run, whether it comes from the CMS, from your site or from chat.
Which sites have database backups
The Database tab is on every site, but only a site on the newer database can be backed up. On a site whose database is on the older database, Backup is greyed out with no Paid badge, whatever the plan, and hovering it reads Backups need a site on the newer database., an empty list reads No database backups with Backups cover sites on the newer database., and the daily run passes the site over.
A site that has no database yet, however old it is, reads No database with Ask chat to create a database first., and hovering Backup reads Create a database before backing it up. Ask chat for a database first, as Site databases describes: it arrives on the newer database, so the site can be backed up from then on. In both cases any backup taken earlier stays in the list, and you can still download or delete it.
There is nothing to work out on your side: whenever Backup is greyed out because of your site or your plan, hovering it names the reason.
Read a database backup
A database backup row reads exactly like a storage one. A backup someone took by hand starts with that person's avatar and is titled with their first name, for example Backup by Sam, or Manual Backup when their name is not known. A daily backup starts with a calendar icon and is titled Daily Backup. A backup taken through chat or a connected AI client with a name of its own shows that name as its title instead.
The line under the title always starts with a type badge, Manual or Daily, followed by the date and time it was taken, how many tables and rows it holds and how big the archive is. Dates and times on a row read in your own timezone. The list loads ten at a time and fetches more as you scroll.
The table count includes the hidden tables the CMS keeps for field settings and multi reference fields, so it can be higher than the number of collections in the CMS sidebar.
While a backup is being made a second badge, Exporting, sits next to the type badge, and the counts and size are left off, because they are not known until it finishes. The row refreshes on its own. If it could not be made that second badge reads Failed, the counts and size stay off, and a small info icon sits right after Failed. Hover or focus the icon to read the reason, exactly as on a storage row. The type badge stays either way.
Back up your database now
Backup sits at the right end of the tab strip while the Database tab is open. Choosing it asks Back up your database now? first. The dialog says every table in your database is exported into a backup you can download later and that your live data is untouched, then tells you what the backup costs from your allowance, in the same words as a storage backup, for example This uses one of your 10 manual backups in the last 24 hours, so 6 will be left.
Confirm with Back up now. The row appears at once as Exporting and fills in when the backup is finished. A backup you ask for is always made, even when nothing has changed since the last one. Only one backup of a site's database runs at a time, so asking for another while one is still exporting is refused with A backup of this database is already running!
One database is exported at a time across the whole platform, so the row can sit as Exporting for a while before the copy itself starts, and what it holds is your data as it stands at that moment rather than at the moment you pressed the button. Wait for the row to show its table and row counts before you clear a collection you meant that backup to hold.
You get ten manual database backups per site in any twenty four hours, counted separately from your storage backups. The button is disabled once they are spent, and hovering it reads You have used all 10 manual backups in the last 24 hours. A backup that fails does not spend one. Deleting a manual backup does not give its slot back either: it keeps counting against the ten until twenty four hours after it was taken.
On a free workspace the button is disabled with a Paid badge beside it, and hovering it reads Backing up your database requires a paid plan. The badge is only shown on a site that could otherwise be backed up, so a site on the older database or with no database gets its own reason instead. If your plan cannot be confirmed, it is disabled with We could not confirm your plan, so database backups are unavailable right now. and no badge. The button is greyed out with no tooltip while the list is still loading, and if the list could not be loaded it stays greyed out with Backups could not be loaded, so a new one cannot start yet. It also waits with Wait for the backups to finish deleting. while Delete backups is still running for this site.
If a backup stops before it finishes, for example because the server restarted, it is marked Failed with The backup stopped before it finished! once it has been running for 30 minutes, by the next backup of that site or simply by opening the tab again, and the daily cleanup removes it once a day has passed since it started.
Turn daily database backups off
Daily database backups are on for every site, including sites created before the switch existed, and they are set apart from daily storage backups. To stop them for one site, open the CMS tab, switch to Settings, and turn off Daily backups in the Backups section. The row reads Archive your database every night. Turning this off stops only the nightly backup, so manual backups still work and existing archives stay. The switch flips at once and you get a Daily backups off toast.
Off means the daily run skips this site's database and nothing else. Backup keeps working, every backup already taken stays listed, downloadable and deletable, and backups keep ageing out on the usual schedule. Daily storage backups carry on as they were.
While daily backups are off, the Database tab of Backups shows one line above the list, Daily backups are off for this site., followed by Turn them back on in CMS settings., which takes you straight to the switch. Turn it back on and you get Daily backups on, and the next daily run picks the site up again.
On a free workspace the switch is disabled with a Paid badge. On a site on the older database it is disabled with no badge, and hovering it reads Backups need a site on the newer database. Any member of the workspace can flip the switch.
Your database pauses while it is backed up
A backup copies the whole database in one piece, and the database does not answer queries while that copy is being made. For a small database this is over almost at once, but a request your site sends in that moment can be slow or fail, so take a manual backup of a busy site at a quiet time. A clone or duplicate that copies your database content takes the same snapshot, so the database pauses then too, and Backup pressed while that copy is being made answers A backup of this database is already running! An export that runs for longer than six minutes is stopped, and the backup is marked Failed with Exporting your database took too long, so this backup was stopped!
What cannot be backed up
Some databases are refused outright rather than backed up in part:
- An empty database. Backup leaves a Failed row reading
Your database has no tables to back up!, while the daily run passes an empty database over quietly. The table the CMS keeps for field settings does not count as a table on its own. - A database that is too large. A database larger than 100 MB is too large for a single archive, and so is one whose exported SQL comes to more than 150 MB. Both fail with
Your database is too large to back up as a single archive! - A database with a full text search table. Such a table cannot be exported, so every backup of that database fails with
Your database has a full text search table, which cannot be backed up!until the table is removed, and the same table stops the site being cloned or duplicated. Chat does not create one unless you ask for full text search, and even then it first tells you that doing so stops your database backups and waits for you to confirm.
When the daily run meets a database that is too large or holds a full text search table, it leaves a Failed row with the reason, so you can see why the site has no recent backup.
Download a database backup
Open the three dots menu on a row and choose Download. The backup downloads as a .zip named after your site and the moment it was taken, in UTC, for example my-site-database-2026-03-04-05-06-07.zip. The row shows that moment in your own timezone, so the hour in the filename can differ from the hour on the row.
Download stays greyed out until a row is finished. On a row still being exported, hovering it reads Wait for the database export to finish before downloading it., and on a row that failed This backup has no database archive to download., because neither has an archive to hand you. If the archive behind a finished row is gone, you are told The archive of this backup is no longer available! instead of getting a broken file.
The download goes through a signed link that stops working 15 minutes after you click Download, so a link copied out of your browser does not stay usable.
What is inside a database backup
The zip holds two files:
database.sqlis your database as a plain text SQL file written for SQLite. It creates each table and inserts every row, one statement per row, then creates your indexes, triggers and views. Open it in any text editor to read or search it, or load it into a SQLite tool, such as thesqlite3command line tool, to query it. It is not written for Postgres, so it cannot be imported into a Postgres database as it is.__modulify-backup.jsonis an index Modulify writes: when the backup was taken, how big the database anddatabase.sqlare, how many tables and rows it holds, the row count of every table, and the identifiers Modulify uses to recognise the database and the moment it was copied.
A database backup cannot be browsed inside Modulify, unlike a storage backup. Downloading is the only way to see what is inside one.
Get data back from a database backup
There is no Restore for a database backup. A row's menu holds Download and Delete and nothing else, the Restore on the Code tab puts back your site's source files without touching the database, Restore backup on a storage backup puts back storage files only, and neither chat nor a connected MCP client can restore or download one.
To get rows back, download a backup that still holds them, find them in database.sql, and add them again. You can enter them one at a time in the CMS, where each new row gets a new id, so links from other collections to the old row have to be picked again. Or paste the rows into chat and ask for them to be added back, which can keep their original ids.
Who can use database backups
A database backup holds every row of your database, so it is guarded like the database itself. Every member of the workspace that owns the site can list and download its database backups. Starting a backup also needs the workspace to be on a paid plan, and deleting one needs the Delete projects permission, so a member without it sees a row's Delete and the Delete backups button in the Danger zone greyed out with a tooltip rather than missing. Turning daily backups on or off needs only membership of the workspace. Anyone outside the workspace is turned away before Modulify even looks the backup up. See Members and roles.
Delete a database backup
Open the three dots menu on a row and choose Delete. It asks Delete this database backup? and warns that the archive is removed for good. A row still exporting keeps its Delete greyed out, and hovering it reads Wait for the database export to finish before deleting it., so delete it once it has finished or failed. If an archive cannot be reached it stays in the list rather than disappearing from it, and Delete on that row says Something went wrong while deleting your database backup! If the row was already removed by someone else, by chat, by a connected AI client or by the daily cleanup, you get Nothing to delete with This database archive was already gone, so the list is up to date. and the row leaves the list.
To clear the whole history at once, open the CMS tab, switch to Settings, and press Delete backups on the Delete all database backups row under Danger zone. It asks Delete every database backup?, warns that every finished archive for the site is removed for good while a backup still being exported is kept, and deletes on Delete all. You get Backups deleted when it is done, Nothing to delete when the site held no finished backup, and Some backups are still there when some could not be reached, which names how many of them are still in the list. The button works on the free plan too, and it waits with a tooltip while the backups of another site are still being deleted. On a site on the older database it is greyed out with Backups need a site on the newer database., so a backup taken there earlier is deleted from its own row instead.
Deleting a backup removes the archive for good. Your live database is untouched, but that copy of it cannot be downloaded again.
Clearing a collection or every collection from the CMS does not delete any backup, so a backup taken before the clear still holds the rows.
How long database backups are kept
Database backups age out exactly like storage backups:
- every daily backup from the last week
- one backup a week back to eight weeks ago
- one backup a month back to a year ago
Anything older than a year is removed, and backups you made yourself are never thinned early, only removed once they pass a year. The newest finished backup of a site is never removed, however old it gets. A backup that failed is cleared from the list by the first daily cleanup after a day has passed since it was attempted.
Database backups when the plan changes
Going from a paid plan to Free stops new database backups. The daily run passes the site over, Backup is disabled with a Paid badge beside it in the tab strip, and the Daily backups switch in CMS settings is disabled with a Paid badge of its own.
The backups already taken are not deleted. You can still download and delete them, and they keep ageing out on the same schedule. Go back to a paid plan and the next daily run picks the site up again, unless daily backups were turned off for it.
Backups from chat and MCP
Storage and database backups can also be handled in plain words. Ask chat and it can:
- list a site's storage or database backups, with the state of each one and whether daily backups are on
- take a manual backup, which spends one of the same ten a site in twenty four hours as Backup and needs the same paid plan
- delete one backup, or every backup of one kind, which needs the Delete projects permission
- turn daily backups on or off for the site, one kind at a time, except that the database switch is refused outright on a site whose database is on the older database, where there is no daily backup to stop
- browse a storage backup folder by folder, or search it by name, and say which of its files are missing from your storage now and which have changed
- read one text file out of a storage backup, so you can see what it held before without putting anything back
- restore a storage backup, whole or in part, after it has shown you what the restore would change and you have said yes
- follow a restore while it runs and tell you when it has finished
Chat asks you before it deletes any backup, and it never deletes backups to save space on its own. It never downloads a backup, or a file out of one, and never hands you a link to one: Download on the row and Download file inside Browse files stay yours. A database backup still cannot be browsed or restored, by chat or by anyone else. Chat cannot list or restore the Code history either, and points you to the Code tab when you ask about an earlier version. While a storage restore is running, chat's storage changes, new storage backups and deletes of the backups the restore uses are refused until it finishes, as While a restore runs describes.
A backup chat starts is reserved straight away and read a little later, exactly as Backup is, so when you ask for one before a clear out, wait for chat to report the row ready before you let it delete or move anything.
Browsing a backup from chat
Ask what a backup holds and chat walks the archive a folder at a time, 100 entries a call, and checks every file in it against your storage as it stands now: same, changed when the file is there at a different size, and missing when it is not there at all, the same three answers the Changed and Missing badges give in Browse files. It compares sizes rather than contents or visibility, so a file edited to exactly the same length reads same, and so does one that has only been made public or private since. Chat can also search the whole archive by name, which lists full paths and compares nothing.
To see what a file held, ask for its contents. Chat reads text files out of the archive, such as .txt, .md, .csv, .json, .html and .css, up to the first 32 KB of one, and says so when the file is longer instead of reading on. Anything else, an image, a video, an audio file or a PDF, is not read at all: chat reports its name, size and type and sends you to Browse files on that row to preview or download it. Browsing and reading need only membership of the workspace and work on every plan, exactly as they do in the tab, and they change nothing in your storage. A backup that is still being archived, one that failed, or one taken in an older format cannot be browsed, and chat gives the reason, such as This backup was taken in an older format that cannot be browsed or restored. Download it instead!
Restoring from chat, in two steps
A restore asked for in chat always takes two steps, and the first one changes nothing. Chat reads the plan back to you first: how many files come back, how many of them are already in your storage with different bytes or visibility, how many files are deleted, how many bytes move, and whether a Before restore backup of your current storage is taken first. Nothing is written while it shows you that, and no row appears in the list.
The restore starts only once you say yes in your own words and chat asks a second time, carrying the confirmation that plan gave it. If your storage changes in between, the confirmation no longer matches what you were shown, the restore is refused with The storage changed since this plan was made, so this confirmation no longer matches. Check the new plan and confirm again!, and chat has to put the new numbers in front of you and ask again. A plan left sitting can never quietly restore something other than what you read.
What runs afterwards is the same job the button starts. It needs a paid plan and the Delete projects permission, only one restore runs per site at a time, a Before restore backup is taken whenever anything would be overwritten or deleted, and the progress shows in the Storage tab for everyone with the editor open. Because it runs in the background, chat follows it and only tells you your files are back once the restore reports completed. Asking for a second restore while one is running is refused, and chat reads out how far the running one has got instead.
The MCP tools
A connected AI client reaches the same things through fourteen MCP tools. Ten cover both kinds of backup, five each: list_storage_backups, create_storage_backup, delete_storage_backup, clear_storage_backups and set_storage_backup_schedule, and list_database_backups, create_database_backup, delete_database_backup, clear_database_backups and set_database_backup_schedule. Four more are storage only: browse_storage_backup, read_storage_backup_file, restore_storage_backup and get_storage_restore_status. Listing needs the sites:read scope, taking a backup and turning daily backups on or off need sites:write, and deleting needs sites:delete, which is unticked by default. Browsing a backup, reading a file out of one and reading how a restore is going need data:read, while starting a restore needs data:write, which is unticked by default too, so a client restores only when you deliberately ticked it. restore_storage_backup is the same two step tool chat uses: the first call answers the plan with started false and changes nothing, and only a second call carrying the confirm value that plan returned starts the restore. set_database_backup_schedule is refused on a site whose database is on the older database, the same as in chat. No tool downloads a backup or a file out of one, and none browses or restores a database backup. While a storage restore is running, the storage tools that change files, create_storage_backup, clear_storage_backups, and delete_storage_backup on the backups the restore uses are refused with a 409 until it finishes, and a second restore_storage_backup answers A restore of this storage is already running! See MCP tools.
The list follows changes made elsewhere
While the editor is open, a Storage or Database list you have already opened updates on its own when a backup is taken, finishes, fails or is deleted, whether you, a teammate, chat, a connected AI client, the daily run or the daily cleanup did it. There is nothing to refresh. A storage restore follows the same way: everyone with the editor open sees its progress, the Before restore backup appears in the list, and an open Storage panel refreshes when the restore finishes. The Daily backups switches follow a change made anywhere else the same way, so a switch flipped by a teammate, from chat or through a connected AI client moves for you too, and the line above the list appears or goes away with it.
Next
- Publish a site pushes a restored state live.
- Site chat explains the transcript that a restore clears.
- Storage covers the files these archives are taken from.
- Site databases covers the database the database backups are taken of.