Model or dataset
timescale/tigerfs avatar
timescale/tigerfs

TigerFS: PostgreSQL mounted as a versioned filesystem

Mount PostgreSQL as a filesystem. Build apps with files, explore databases with ls and cat. Every write is logged and undoable.

715 stars26 forksGoMIT

At a glance

What is it?
TigerFS presents a PostgreSQL database through FUSE on Linux and NFS on macOS, where files are rows, directories are tables and every write is logged and reversible. It is aimed at coding agents that need a transactional file interface, and it ships agent skills for Claude Code, Gemini CLI and Codex.
Who is it for?
Adopt TigerFS when several agents and people need to edit the same PostgreSQL data through ordinary file operations and you want a reversible record of every change, and when you accept that the mount is a daemon speaking FUSE or NFS rather than a local disk.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 22 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Rows become files and tables become directories

TigerFS is two ideas in one codebase. The first is a versioned filesystem whose backend happens to be PostgreSQL, where every file is a real row, directories are tables and file contents are columns. The second is a filesystem interface onto an existing database, so any Postgres instance can be mounted and explored with ordinary Unix tools.

The stated design goal is that the filesystem is the API. Multiple agents and humans can read and write the same files concurrently with full ACID guarantees, every change is versioned and fully reversible, and there is no sync protocol and no coordination layer in between. That last point is the interesting one. The usual reason teams reach for files when several agents work on one body of work is that files are easy to copy around and easy to merge, and a merge protocol is exactly the fragile part. Here the database transaction is the concurrency control, and the filesystem is only the surface.

The audience is specific: coding agents, and the humans supervising them. The project describes itself as built for agents, and the shipped agent skills target Claude Code, Gemini CLI, Codex and others. The implementation is Go, with the module named github.com/timescale/tigerfs and an MIT licence, so the Timescale name in the path is a vendor, not a dependency on a TimescaleDB instance.

The dot-directory surface where history and queries live

Data lives in ordinary files and directories, but metadata, queries and operations live in dot-directories that are invisible to a normal listing and always available:

bash
$ ls /mnt/db/notes/
hello.md  tutorials/

$ ls -a /mnt/db/notes/
.  ..  .history/  .log/  .savepoint/  .undo/  hello.md  tutorials/

The two modes use different dot-directories over the same transactional database. In file-first mode, .history/ holds past versions of a file, .log/ holds the operation log with diffs, .savepoint/ holds bookmarks for undo, .undo/ previews and applies an undo, and .build/ creates workspaces. In data-first mode, .info/ exposes table metadata, .by/ does index lookups, .filter/ filters by column, .order/, .first/ and .last/ sort and paginate, .export/ and .import/ handle bulk input and output, and .create/, .modify/ and .delete/ manage schema.

The data-first path syntax is the cleverest part. Filters chain into a directory path that pushes down to SQL, so the last 10 orders for one customer is a path ending in .last/10/.export/json rather than a query. An agent can therefore explore a large database with ls, cat and grep and never write SQL, while the pushdown keeps the work in the database.

Installing the binary and mounting a database

Installation is a single command, and the project says to pick a mode depending on what you have: a new project should start file-first, an existing database should start data-first.

bash
curl -fsSL https://install.tigerfs.io | sh

Mounting takes a Postgres connection string and a mount point:

bash
tigerfs mount postgres://localhost/mydb /mnt/db

The transport differs by platform. On Linux the mount goes through FUSE, and on macOS through NFS, and the project states that no extra dependencies are needed. The Go module confirms the mechanism: it depends on github.com/hanwen/go-fuse/v2 and github.com/willscott/go-nfs. A userland NFS server on macOS is a different thing from a kernel NFS client, and the project describes the mount as going through NFS rather than as a native macOS mount, which is a detail worth confirming on your own machine before you depend on it.

The dependency list also shows the shape of the codebase. The database access is pgx, the command line is cobra with viper for configuration, logging is zap, the Go version required is 1.25.1, and the test suite pulls in testcontainers with a Postgres module, so the integration tests are expected to run against a real database in a container rather than a mock.

A workspace turns a table into a directory of markdown

A workspace tells TigerFS how to present a table as a native file format. Writing the word markdown into .build/ turns the table into a directory of .md files with YAML frontmatter, and adding history to the same declaration opts the workspace into automatic versioning:

bash
echo "markdown,history" > /mnt/db/.build/blog

From there, a post is a file, and the frontmatter becomes columns while the body becomes text:

bash
cat > /mnt/db/blog/hello-world.md << 'EOF'
---
title: Hello World
author: alice
tags: [intro]
---

# Hello World

Welcome to my blog...
EOF

The payoff is that every existing file tool works against it. Searching for content by author is a grep over the frontmatter, and directories are real directories, so mkdir creates a folder and mv moves a file between them:

bash
mkdir /mnt/db/blog/tutorials
mv /mnt/db/blog/hello-world.md /mnt/db/blog/tutorials/

That is also where the multi-agent story gets concrete. The documentation describes coordinating agents by moving files between todo, doing and done directories, which means task state is expressed as directory membership and the transitions are transactional writes that show up in the operation log. The column mapping and frontmatter handling details live in docs/file-first.md, so the format is documented rather than implicit.

Savepoints turn an agent edit session into a reversible sandbox

Workspaces that declare the history feature capture every write, including creates, edits, renames and deletes, in the operation log with a timestamp and a user identity. The user identity is what makes the multi-agent case work, since the log can be filtered by which agent made a change.

Past versions are browsable as files, one stored version per entry:

bash
ls /mnt/db/notes/.history/plan.md/                          # all stored versions
cat /mnt/db/notes/.history/plan.md/2026-04-12T14:23:00Z     # one specific version

The operation log can be read the same way, filtered by recency or by user, and any individual edit can be diffed:

bash
cat /mnt/db/notes/.log/.last/10/.export/json                      # 10 most recent operations
cat /mnt/db/notes/.log/.by/user_id/agent-7/.last/5/.export/json   # filtered by user
diff -u /mnt/db/notes/.log/<id>/before /mnt/db/notes/.log/<id>/current  # diff a specific edit

Savepoints are the mechanism for trying something and backing out. A named bookmark is created, changes are made, the pending undo is diffed for review, and the undo is applied only when a marker file is touched:

bash
echo '{"description":"Before refactoring"}' > /mnt/db/notes/.savepoint/before-refactor.json
# ... edit multiple files ...
diff -ru /mnt/db/notes/.undo/to-savepoint/before-refactor /mnt/db/notes/ -x '.*'  # review
touch /mnt/db/notes/.undo/to-savepoint/before-refactor/.apply                     # apply

Review before apply, in that order, is the design point. An agent that refactors twenty files can show the diff and then either commit the change or discard it in one step. Auto-savepoints are also available, with the flag --auto-savepoint-interval and a default of 30m, recording bookmarks at session-boundary inactivity gaps so a recent checkpoint always exists.

Agent skills are installed at mount time

The project bundles skills for agents rather than expecting the agent to learn the interface from documentation. They are installed automatically when the filesystem is mounted, and they cover reading, writing, searching and, as of version 0.7, safely rolling back a change. The documentation states that you do not need to learn the filesystem interface and can simply ask.

The published example requests show both modes in use. A file-first request sets up a workspace for notes or a kanban board for a sprint with todo, doing and done columns, sets a savepoint before refactoring code and reverts if the tests fail, and asks what agent-7 changed in the last hour so that just those edits can be undone. A data-first request finds a customer by email address and bumps their tier to premium, or shows the last 10 orders for a given customer.

The mechanism behind this is the same dot-directory control surface, since the skills are teaching agents to use paths for index lookups, pipeline filters with SQL pushdown, PATCH updates and DDL through .create/ and .delete/. The repository ships a skills/ directory at the top level, next to a CLAUDE.md, a Dockerfile, a goreleaser configuration for releases, cmd/ for the command line, internal/ for the implementation and test/ for the tests. What the skills buy you is not new capability but a shared vocabulary, and that is the part that makes several agents agree on how to undo a change.

Where the container build and the release cadence will catch you out

The Dockerfile is a multi-stage build with a Go builder stage and an Alpine runtime, and it is written in a way that reveals the real dependency. The build stage installs git and fuse-dev, and the binary is compiled with CGO_ENABLED=1, which is required for FUSE. The final stage installs fuse and ca-certificates, creates a non-root user with uid 1000, prepares /mnt/db owned by that user and runs the binary as that user.

There is a version mismatch worth catching early. The go.mod file requires Go 1.25.1, while the builder stage is pinned to golang:1.23-alpine. A build on that image either fails or depends on toolchain behaviour you did not intend, and it is exactly the kind of mismatch that a container build surfaces on someone else's machine rather than yours.

The release cadence is another factor. The tags are v0.5.0 from 2026-02-28, v0.6.0 from 2026-03-27 and v0.7.0 from 2026-06-02, and the last push to the repository was on 2026-10-01. The project is pre-1.0 and moving quickly, which suits an agent tool that wants new capabilities, and it does not suit a team that needs a version contract with a support commitment. The document also names only FUSE on Linux and NFS on macOS, and it does not describe a Windows path, so a mixed-OS team has to plan around that.

Finally, the alternative deserves a fair hearing. A SQL client such as psql is a smaller dependency, faster to start and better at reporting, and it is the right tool for a person who wants to run one query. What TigerFS changes is that the write path becomes a file write with an operation log and a rollback, and that an agent can explore a schema with ls and grep without holding a query in context. If your need is read-only exploration of a large table, a client and a query planner will beat a mount.

Editorial conclusion

Adopt TigerFS when several agents and people need to edit the same PostgreSQL data through ordinary file operations and you want a reversible record of every change, and when you accept that the mount is a daemon speaking FUSE or NFS rather than a local disk. Do not adopt it to replace a database client for one-off queries, for a workload that needs a platform the project does not name, or for a team that wants a stable release contract, since the newest tagged release is v0.7.0 from 2026-06-02 and the last push was on 2026-10-01. Before you commit, run the hello_world example against your own Postgres, check that the container build works on your host given the Go 1.25.1 requirement against the golang:1.23-alpine base image, and confirm that the FUSE or NFS mount behaves under the load your agents will put on it.

Frequently asked questions

What is TigerFS and who is it for?

TigerFS is a versioned filesystem backed by PostgreSQL that also works as a filesystem interface to an existing database, mounting through FUSE on Linux and NFS on macOS. The project describes itself as built for agents, and it ships agent skills for Claude Code, Gemini CLI and Codex that are installed at mount time.

How do I install TigerFS and mount a database?

Installation is a single command, curl -fsSL https://install.tigerfs.io | sh, and mounting takes a connection string and a mount point, for example tigerfs mount postgres://localhost/mydb /mnt/db. The project says to start file-first for a new project and data-first for an existing database.

How do I undo a change in TigerFS?

Every write is captured in the operation log, and a savepoint can be created as a named bookmark before changes are made. The pending undo is reviewed with a diff and then applied by touching a marker file in the .undo/ directory, and version 0.7 added the ability for an agent to roll back a change safely.

Can I query a large database with TigerFS without writing SQL?

Yes. In data-first mode filters chain into directory paths that push down to SQL, and the documented example finds the last 10 orders for one customer at a path ending in .last/10/.export/json. Dot-directories also cover index lookups in .by/, column filtering in .filter/ and schema management in .create/, .modify/ and .delete/.

What licence is TigerFS under and is it stable?

The repository is under the MIT licence and the module is github.com/timescale/tigerfs. The project is pre-1.0, with tags v0.5.0, v0.6.0 and v0.7.0 published between February and June 2026, and the last push to the repository was on 2026-10-01.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. timescale/tigerfs on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/timescale-tigerfs.svg)](https://hysenlabs.com/projects/timescale-tigerfs)

Was this useful?