DEV Community

Cover image for TigerFS: A Filesystem Backed by PostgreSQL
Polliog
Polliog

Posted on

TigerFS: A Filesystem Backed by PostgreSQL

TigerFS is a filesystem backed by PostgreSQL, built by the Timescale team. It mounts a database as a local directory via FUSE on Linux and NFS on macOS. Every file is a real row. Every directory is a table. Writes are transactions. Multiple processes and machines can read and write concurrently with full ACID guarantees.

There are two distinct ways to use it.

# Install (Linux requires fuse3; macOS needs no extra dependencies)
curl -fsSL https://install.tigerfs.io | sh

# Mount any PostgreSQL database
tigerfs mount postgres://localhost/mydb /mnt/db
Enter fullscreen mode Exit fullscreen mode

Mode 1: Data-First

Mount any existing PostgreSQL database and explore it with standard UNIX tools. Every path resolves to optimized SQL that gets pushed down to the database.

Exploring

ls /mnt/db/                                          # list tables
ls /mnt/db/users/                                    # list rows by primary key
cat /mnt/db/users/123.json                           # read a row as JSON
cat /mnt/db/users/123/email.txt                      # read a single column
cat /mnt/db/users/.by/email/alice@example.com.json   # lookup by indexed column
Enter fullscreen mode Exit fullscreen mode

Modifying

echo 'new@example.com' > /mnt/db/users/123/email.txt          # update a column
echo '{"email":"a@b.com","name":"A"}' > /mnt/db/users/123.json  # PATCH via JSON
mkdir /mnt/db/users/456                                         # insert a row
rm -r /mnt/db/users/456/                                        # delete a row
Enter fullscreen mode Exit fullscreen mode

Pipeline Queries

Filters, ordering, and pagination can be chained directly in the path. TigerFS executes the whole chain as a single SQL query:

# Last 10 orders for customer 123, sorted by created_at, as JSON
cat /mnt/db/orders/.by/customer_id/123/.order/created_at/.last/10/.export/json

# Shipped orders, specific columns only, as CSV
cat /mnt/db/orders/.filter/status/shipped/.columns/id,total,created_at/.export/csv
Enter fullscreen mode Exit fullscreen mode

Available segments (chainable in any order):

Segment Description
.by/col/val Indexed filter
.filter/col/val Any column filter
.order/col Sort
.columns/a,b,c Column projection
.first/N, .last/N, .sample/N Pagination
`.export/json\ csv\

Bulk Ingest

{% raw %}

cat data.csv > /mnt/db/orders/.import/.append/csv    # append rows
cat data.csv > /mnt/db/orders/.import/.sync/csv      # upsert by primary key
cat data.csv > /mnt/db/orders/.import/.overwrite/csv # replace the table
Enter fullscreen mode Exit fullscreen mode

Schema Management

Tables, indexes, and views are managed through a staging pattern:

mkdir /mnt/db/.create/orders
echo "CREATE TABLE orders (...)" > /mnt/db/.create/orders/sql
touch /mnt/db/.create/orders/.commit
Enter fullscreen mode Exit fullscreen mode

Mode 2: File-First

Create a new database and use it as a transactional shared workspace. Any tool that works with files works here: AI agents, grep, vim, shell scripts.

Markdown Apps

"Apps" define how TigerFS presents a table as a native file format. Writing markdown to .build/ turns a table into a directory of .md files where YAML frontmatter maps to columns and the document body maps to a text column:

echo "markdown" > /mnt/db/.build/blog

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

# Hello World

Welcome to my blog...
EOF

# Standard tools work as expected
grep -l "author: alice" /mnt/db/blog/*.md
mkdir /mnt/db/blog/tutorials
mv /mnt/db/blog/hello-world.md /mnt/db/blog/tutorials/
Enter fullscreen mode Exit fullscreen mode

Version History

Add history to the app definition and every edit is captured as a timestamped snapshot in a read-only .history/ directory. History uses TimescaleDB hypertables for compressed storage and tracks files across renames via stable row UUIDs:

echo "markdown,history" > /mnt/db/.build/notes

ls /mnt/db/notes/.history/hello.md/
# 2026-02-24T150000Z  2026-02-12T013000Z

cat /mnt/db/notes/.history/hello.md/2026-02-12T013000Z
Enter fullscreen mode Exit fullscreen mode

Multi-Agent Task Queue

mv between directories is an atomic database operation. Two agents cannot claim the same task because the underlying transaction will fail for one of them - no distributed lock manager, no coordination API needed:

echo "markdown,history" > /mnt/db/.build/tasks
mkdir /mnt/db/tasks/todo /mnt/db/tasks/doing /mnt/db/tasks/done

cat > /mnt/db/tasks/todo/fix-auth-bug.md << 'EOF'
---
priority: high
assigned_to:
---
The OAuth token refresh is failing for users with...
EOF

# Agent claims the task - atomic database operation
mv /mnt/db/tasks/todo/fix-auth-bug.md /mnt/db/tasks/doing/fix-auth-bug.md

# Agent marks it done
mv /mnt/db/tasks/doing/fix-auth-bug.md /mnt/db/tasks/done/fix-auth-bug.md

# Check what is in progress
ls /mnt/db/tasks/doing/
grep "assigned_to:" /mnt/db/tasks/doing/*.md
Enter fullscreen mode Exit fullscreen mode

Shared Agent Workspace

Multiple agents on different machines can read and write the same files concurrently. Changes are visible immediately with no pull, push, or merge step:

# Agent A writes findings
cat > /mnt/db/kb/auth-analysis.md << 'EOF'
---
author: agent-a
---
OAuth 2.0 is the recommended approach because...
EOF

# Agent B reads immediately, no sync needed
cat /mnt/db/kb/auth-analysis.md

# Agent B updates the document
cat > /mnt/db/kb/auth-analysis.md << 'EOF'
---
author: agent-a
reviewed-by: agent-b
status: approved
---
OAuth 2.0 is the recommended approach because... [approved with comments]
EOF

# Full edit trail
ls /mnt/db/kb/.history/auth-analysis.md/
Enter fullscreen mode Exit fullscreen mode

Cloud Backends

TigerFS works with any PostgreSQL database via connection string. It also integrates with Timescale Cloud and Ghost through their CLIs - no passwords stored in config:

tigerfs mount postgres://user:pass@host/mydb /mnt/db

tigerfs mount tiger:abcde12345 /mnt/db   # Timescale Cloud
tigerfs mount ghost:fghij67890 /mnt/db   # Ghost

# Fork a database for safe experimentation
tigerfs fork /mnt/db my-experiment
Enter fullscreen mode Exit fullscreen mode

Why the File Interface

The point of the filesystem abstraction is that every tool already speaks it. grep, awk, jq, shell scripts, AI coding agents (Claude Code, Cursor, and others) all understand files without any SDK, schema definition, or client library to set up.

For multi-agent coordination specifically:

Approach What you build on top
Custom REST API Endpoints, auth, deployment
Shared database directly SQL or ORM, schema definitions, client libraries
Git Pull/push/merge workflow, conflict resolution
S3 No transactions, no structured queries
TigerFS Mount and use standard tools

The coordination logic - atomic task claims, version history, concurrent access - lives in PostgreSQL. The application doesn't implement it.


Current Status

TigerFS is at v0.5.0 and described as early-stage by the team, though the core design is stable. The data-first mode is functional today for any PostgreSQL database. Planned additions include support for tables without primary keys (read-only via ctid) and TimescaleDB hypertable time-based navigation.

GitHub: timescale/tigerfs - Docs: tigerfs.io

tigerfs mount postgres://localhost/yourdb /mnt/db
ls /mnt/db/
Enter fullscreen mode Exit fullscreen mode

Top comments (0)