Data & Portability
Content you can open in a text editor
Every object is a file on disk. There is no database to provision, secure, back up or keep in sync with your uploads — a backup is a copy of a folder.
All Total CMS data lives in a folder — tcms-data in the document root by default, and configurable elsewhere. Inside it there is one folder per collection, and inside that, one JSON file per object named after its id. A blog post is literally tcms-data/blog/hello-total-cms.json. Open it in your editor, diff it, commit it, script against it.
Three files describe a collection. .meta.json holds its settings: name, description, the schema it conforms to, the URL its objects live at, and any form-label overrides. .index.json holds a summary of every object in the collection — only the properties the schema names in its index array, so listing a collection never has to open every file. And each object's assets sit in a folder named for the object, then for the property, so a gallery image on a post is at my-blog-post/gallery/image.jpg. Delete the object folder and its uploads go with it.
Schemas are JSON too, written in the standard JSON Schema format. Those that ship with Total CMS live with the source; your own custom schemas live in tcms-data/.schemas/. Alongside them, tcms-data/.system/ holds the installation's operational state — settings, extension permissions, OAuth signing keys, and site.key, the encryption secret that anything encrypted on this site can only be decrypted with. Include .system in your backups; it is part of the deployment's identity.
JSON is the default, not the only option. A collection can be created with a storage format of markdown instead, storing each object as {id}.md: YAML frontmatter for every property, plus a body taken from the schema's content property. That is the format for content people would rather edit in a text editor or a git repository than through a form — documentation sites, markdown-first blogs. The format is fixed at creation; tcms collection:convert is the only thing that changes the setting and the files together, and it is safe to interrupt and re-run.
Editing files by hand is a supported workflow with one rule: a hand-edited file is invisible until the index is rebuilt. Edit, commit, deploy, then run tcms repair:index {collection}. A file that will not parse is skipped and named rather than failing the whole build. Everything above the repository — the REST API, MCP, Twig, sync, JumpStart, exports, the admin — reads through the same layer and never needs to know which format a collection uses.
What you get
One folder per collection
Objects are named JSON files, and each object's uploads live in a folder beside it, grouped by property. Moving a site is moving a directory.
Indexed for fast reads
A collection's .index.json summarises every object using the properties the schema lists in its index array, so listings never open every file.
Markdown when a document suits better
A collection can store objects as .md files — YAML frontmatter plus a body from the content property. Perfect for docs sites kept in git.
Hand edits are a workflow
Edit files in your editor, commit, deploy, then run tcms repair:index. Unparseable files are skipped and named rather than breaking the collection.
Back up .system
tcms-data/.system holds settings, extension state, OAuth keys and site.key — the secret your encrypted values depend on. It belongs in every backup.
In practice
One snippet
# One object, one file — read it, diff it, commit it
cat tcms-data/blog/hello-total-cms.json
# Store a collection as markdown instead of JSON
tcms collection:convert docs --to=markdown --dry-run
tcms collection:convert docs --to=markdown
# Make hand-edited files visible to the CMS
tcms repair:index docs
The storage format is a collection setting, and the CLI converts an existing collection in place.
FAQ
Common questions
Is there really no database?
None. Every object, schema and collection setting is a file on disk. There is nothing to provision, tune, secure or keep consistent with your uploads.
Can I edit the files by hand?
Yes, and it is a documented workflow: edit, commit, deploy, then run tcms repair:index for that collection. Bear in mind that a file edited outside Total CMS bypasses schema validation entirely.
What has to be in a backup?
The whole tcms-data directory, including the hidden .system folder. It holds settings, extension state, OAuth signing keys and site.key, without which encrypted values on that site cannot be decrypted.
Can I switch a collection from JSON to markdown later?
Yes, with tcms collection:convert. The format cannot be changed by editing the setting — the command flips the setting and rewrites the files together, and is safe to interrupt and re-run.
Related features
- JumpStart export/import Export schemas, collections, objects and templates to one JSON file and import it anywhere. Faker-backed factory blocks generate sample content on the way in.
- Push & pull sync Deploy schemas, templates and collection settings from local to production with tcms push — content stays put, and a dry run shows what changes first.
- 20+ built-in content types Blog, image, gallery, file, depot, text, number, date, toggle, color, url, email, svg and feed schemas ship built in. Bind one to a collection and edit.
Want the details? Read the Flat-file storage documentation →
Or keep browsing: every Total CMS feature →
Start Your Free 45-Day Trial