What Is πfs, Why Does It Exist, How Does It Work, and What Can It Teach Us?
Updated: September 2026
πfs—pronounced “Pi FS” and commonly represented by the repository name pifs—is one of the strangest, funniest, and surprisingly educational filesystem experiments ever created.
Its central idea sounds impossible:
Instead of storing your files on disk, find their contents somewhere inside the digits of π and store only information describing where those contents can be found.
If π contains every possible finite sequence of digits, then somewhere inside π should be:
- every text file,
- every image,
- every program,
- every video,
- every database,
- every ZIP archive,
- every file that has ever existed,
- and every finite file that could ever exist.
So why store the file itself?
Why not just store its location inside π?
That is the joke—and the computer science lesson—behind πfs.
πfs is a real FUSE filesystem written in C by Philip Langdale. It can be compiled and mounted on Linux, and ordinary commands such as cat, echo, cp, ls, and editors can interact with it through the filesystem interface. The project describes itself as a “data-free filesystem,” although, as we will discover, the metadata required by the implementation is actually larger than the original data.
Today, πfs should be considered an experimental/educational filesystem and an information-theory thought experiment—not a production storage technology. The repository now explicitly directs users toward its newer spiritual successor, InferenceFS.
1. What Is πfs?
πfs is a userspace filesystem that represents file bytes using positions in the hexadecimal expansion of π.
Conceptually, instead of storing:
Hello World
the filesystem tries to store something conceptually resembling:
byte H -> position X in π
byte e -> position Y in π
byte l -> position Z in π
...
When the file is read again, πfs calculates the corresponding digits of π and reconstructs each byte.
The filesystem interface is provided through FUSE—Filesystem in Userspace.
FUSE allows a normal userspace application to behave like a filesystem. The Linux kernel forwards filesystem operations such as:
open()
read()
write()
mkdir()
unlink()
stat()
to the userspace filesystem implementation.
Modern libfuse documentation describes exactly this architecture: a standalone userspace process receives filesystem requests from the kernel through libfuse callbacks.
πfs implements those callbacks itself.
2. The Big Idea Behind πfs
Suppose π were a normal number.
Informally, a number is normal in a base if every finite sequence of digits occurs with the expected frequency.
For base 16, this would imply that sequences such as:
00
01
02
...
FE
FF
all appear repeatedly.
Longer sequences would also occur:
48656C6C6F
which is hexadecimal for:
Hello
and so would every other finite hexadecimal sequence.
Therefore, if π is normal in base 16, every finite binary file can theoretically be represented somewhere within its hexadecimal expansion.
There is one enormous caveat:
π has not been proven to be normal.
The πfs premise relies on a widely studied but unproven property of π. Even the project’s issue tracker contains discussion pointing out that the required property has not been proven.
So the theoretical statement is:
If π is normal—or at least contains every finite hexadecimal sequence—then every finite file occurs somewhere in π.
Not:
“Mathematics has proven that every possible file is inside π.”
That distinction matters.
3. Why Hexadecimal?
Computers store bytes.
One byte contains:
8 bits
and therefore has:
2^8 = 256
possible values.
A byte maps cleanly to two hexadecimal digits:
00000000 -> 00
00000001 -> 01
...
11111111 -> FF
So a binary file can simply be interpreted as a hexadecimal digit sequence.
For example:
Hello
becomes:
48 65 6C 6C 6F
πfs therefore works naturally with hexadecimal digits of π.
4. The Bailey–Borwein–Plouffe Formula
A major ingredient in πfs is the Bailey–Borwein–Plouffe formula, commonly called BBP.
It can be written as:
Why is this interesting?
Because BBP allows hexadecimal digits of π near a particular position to be calculated without first calculating every preceding digit.
That gives πfs something similar to random access into π.
The bundled piqpr8.c implementation describes itself as computing hexadecimal digits beginning at an arbitrary position. Its source notes that with IEEE 64-bit floating-point arithmetic, that implementation is reliable only up to roughly positions.
That is an important engineering distinction:
BBP helps retrieve digits at a known location.
It does not magically tell you where an arbitrary file occurs in π.
Finding the position is still a search problem.
5. What πfs Actually Does
This is where the implementation becomes much more interesting than the headline.
The original README explains that files are divided into individual bytes rather than attempting to search π for an entire file at once.
For every byte being written, the implementation effectively does:
for candidate_position = 0 ... maximum_position:
calculate byte from π at candidate_position
if calculated_byte == wanted_byte:
save candidate_position
stop searching
Code language: JavaScript (javascript)
The actual source contains essentially this algorithm:
for (index = 0; index < SHRT_MAX; index++) {
if (get_byte(index) == *buf) {
break;
}
}
write(info->fh, &index, sizeof index);
Code language: HTML, XML (xml)
So πfs does not search π for your complete 10 MB photograph.
Instead, it searches for each possible byte independently.
6. πfs Architecture
The architecture can be visualized as:
Application
|
open/read/write
|
v
Linux VFS Layer
|
v
FUSE Kernel
|
v
libfuse
|
v
+-----------+
| πfs |
+-----------+
/ \
/ \
v v
Metadata Directory BBP Algorithm
------------------ -------------
file paths calculate
byte offsets digits of π
permissions
timestamps
For writes:
Application
|
| write byte
v
πfs
|
| search positions in π
v
BBP get_byte()
|
| find matching byte
v
position/index
|
v
metadata file
For reads:
Application
|
| read()
v
πfs
|
| read stored index
v
metadata
|
v
BBP get_byte(index)
|
v
original byte
7. The Metadata Directory
πfs requires one important custom configuration parameter:
mdd=<metadata-directory>
Code language: HTML, XML (xml)
Example:
πfs -o mdd=/home/user/pifs-meta /home/user/pifs-mount
Code language: JavaScript (javascript)
The repository defines only one πfs-specific option:
struct options {
char *mdd;
};
PIFS_OPT_KEY("mdd=%s", mdd, 0)
Code language: JavaScript (javascript)
and refuses to start unless that directory exists and is readable, writable, and executable by the process.
The metadata directory holds the actual filesystem structure underlying πfs.
8. The Great πfs Punchline: Metadata Is Bigger Than the Data
Suppose your file contains one byte:
A
The current implementation searches π for that byte and stores its position using:
short index;
On typical modern Linux systems:
sizeof(short) = 2 bytes
So roughly:
1 byte logical data
↓
2 bytes πfs metadata
For a 1 MB file:
Logical file:
~1 MB
πfs position metadata:
~2 MB
The code explicitly seeks through the backing metadata using:
offset * 2
and its path-based getattr() divides the physical metadata size by two before reporting the logical size.
So instead of infinite compression, this implementation typically produces something close to:
Compression ratio ≈ -100%
or, more plainly:
Storage used ≈ 200% of the original file
before counting filesystem metadata.
This is intentional comedy—but also a superb information-theory demonstration.
9. Why πfs Cannot Beat Information Theory
Imagine a random file containing N bits.
There are:
possible N-bit files.
If a lossless compression system mapped every possible N-bit file to fewer than N bits, there would not be enough shorter representations available.
This follows directly from the pigeonhole principle.
Some data can certainly be compressed:
AAAAAAAAAAAAAAAAAAAAAAAA
contains strong redundancy.
But random-looking data such as encrypted or already-compressed data usually contains little exploitable redundancy.
πfs does not make that information disappear.
Instead, it effectively moves the information into:
positions inside π
The location information must contain enough information to distinguish the original content.
The “address” becomes the data.
That is the deeper lesson behind πfs.
10. Why Searching for an Entire File Would Be Worse
Suppose π behaves approximately like a random stream of hexadecimal digits.
There are:
256
possible one-byte values.
Finding a particular byte would therefore require, very roughly, hundreds of candidate positions.
But a two-byte value has:
256² = 65,536
possibilities.
Three bytes:
256³ = 16,777,216
Four bytes:
256⁴ = 4,294,967,296
For an N-byte random string, its expected location grows on the rough scale of:
The binary representation of an index that large itself approaches approximately:
8N bits
—the size of the original file.
And searching such a space would be computationally absurd.
Breaking the file into individual bytes therefore makes the demo executable, but destroys any supposed storage advantage.
11. What Happens During a Write?
Consider:
printf A > file.txt
Code language: CSS (css)
The application calls:
write()
FUSE forwards that request to πfs.
πfs executes its pifs_write() callback.
For the byte A, πfs repeatedly calls:
get_byte(index)
starting from index zero.
get_byte() invokes the BBP-related calculations in piqpr8.c.
Eventually:
calculated byte == A
πfs writes the corresponding numeric index into the metadata file.
For another byte, the process starts again.
And again.
And again.
The current implementation does not maintain a permanent precomputed 256-byte lookup table during the write process; each byte performs the search loop shown in the source.
That contributes heavily to its poor write performance.
12. What Happens During a Read?
Reading reverses the process.
The metadata might conceptually contain:
23
91
37
37
105
πfs reads each stored index and executes:
get_byte(23)
get_byte(91)
get_byte(37)
...
Each call calculates the appropriate digits of π.
Those values reconstruct the logical file.
The actual read callback loads a short index and passes it into get_byte(index).
13. Why πfs Uses FUSE
Writing an ordinary kernel filesystem would require kernel-level filesystem code.
FUSE provides a much simpler model.
An application performs:
cat /mnt/pifs/example.txt
Linux sees:
/mnt/pifs
as a mounted filesystem.
The request travels:
Application
↓
Linux VFS
↓
FUSE kernel interface
↓
libfuse
↓
πfs userspace process
Code language: PHP (php)
πfs produces the data and sends it back.
This makes πfs particularly useful for learning how virtual filesystems work.
14. πfs Source-Code Components
The repository is pleasantly small.
The core pieces are:
pifs/
├── autogen.sh
├── configure.ac
├── Makefile.am
└── src/
├── Makefile.am
├── πfs.c
└── piqpr8.c
πfs.c
Implements the FUSE filesystem.
Among its callbacks are:
getattr
readlink
mknod
mkdir
unlink
rmdir
symlink
rename
link
chmod
chown
truncate
open
read
write
statfs
release
fsync
setxattr
getxattr
listxattr
removexattr
opendir
readdir
create
lock
utimens
piqpr8.c
Contains the BBP-based hexadecimal π digit implementation.
Its public function is:
unsigned char get_byte(int id)
which generates two hexadecimal digits and combines them into one byte.
configure.ac
The build configuration declares:
πFS version 1.0
C99
FUSE >= 2.8
That FUSE requirement becomes important on modern Linux distributions.
15. πfs and FUSE 2 vs FUSE 3
The original code defines:
#define FUSE_USE_VERSION 26
Code language: CSS (css)
and includes:
#include <fuse/fuse.h>
Code language: HTML, XML (xml)
Its build system specifically asks pkg-config for:
fuse >= 2.8
In other words:
πfs is a FUSE 2-era application.
Modern libfuse development primarily revolves around FUSE 3. As of 2026, upstream libfuse has reached the 3.18 generation.
Fortunately, several distributions still provide compatibility development packages for FUSE 2.
For example, Ubuntu 24.04 provides:
libfuse-dev 2.9.9
Code language: CSS (css)
Fedora also continues publishing FUSE v2 fuse-devel packages; Fedora 45 has FUSE 2.9.9 development files available.
16. Recommended Environment in 2026
For the least-friction experiment, use:
Ubuntu 24.04 LTS
Code language: CSS (css)
or another Linux environment where the complete FUSE 2 stack is readily available.
Ubuntu 24.04 still provides both the FUSE 2 development library and FUSE 2 utility package.
Newer distributions are gradually transitioning their command-line FUSE tooling to FUSE 3.
For example, Debian 13/Trixie’s fuse package is now transitional and depends on fuse3, although the FUSE 2 development library remains available.
Similarly, Ubuntu 26.04 keeps the FUSE 2 development library but its fuse source package no longer produces the old FUSE 2 utility binary.
Therefore, for learning πfs rather than debugging old FUSE compatibility:
Ubuntu 24.04 is a particularly convenient demo environment.
17. Installing πfs on Ubuntu 24.04
Start by updating package metadata:
sudo apt update
Install the compiler and build dependencies:
sudo apt install \
git \
build-essential \
autoconf \
automake \
autotools-dev \
pkg-config \
libfuse-dev
Verify the FUSE 2 development package:
pkg-config --modversion fuse
You should see something similar to:
2.9.9
Code language: CSS (css)
Check whether the FUSE mount helper is available:
command -v fusermount
If your Ubuntu 24.04 installation does not contain it, inspect the package transaction and install the FUSE 2 utility package:
sudo apt install fuse
Ubuntu 24.04 publishes the FUSE 2.9.9 utility package separately from FUSE 3.
18. Clone πfs
Clone the repository:
git clone https://github.com/philipl/pifs.git
Code language: PHP (php)
Enter it:
cd pifs
Inspect the project:
ls
You should see files including:
README.md
autogen.sh
configure.ac
Makefile.am
src/
19. Generate the Build System
Run:
./autogen.sh
An interesting minor detail: the current autogen.sh already executes:
autoreconf --install
and then runs:
configure
itself.
Therefore the README sequence:
./autogen.sh
./configure
contains a redundant second configure step.
It is harmless, but normally:
./autogen.sh
make
is sufficient.
20. Compile πfs
Run:
make
or:
make -j"$(nproc)"
Code language: JavaScript (javascript)
The resulting program should appear as:
src/πfs
Verify:
ls -l src/πfs
You can experiment without globally installing anything.
21. Optional System Installation
If you want the executable in the system path:
sudo make install
Then:
command -v πfs
may return something similar to:
/usr/local/bin/πfs
The executable itself genuinely contains the Unicode character:
π
in its name.
If typing that is inconvenient, create a shell alias:
alias pifs='πfs'
Code language: JavaScript (javascript)
or a symlink:
sudo ln -s /usr/local/bin/πfs /usr/local/bin/pifs
Then you can run:
pifs
instead.
22. Create the πfs Directories
πfs needs two directories.
Metadata directory
mkdir -p ~/pifs-meta
Mount point
mkdir -p ~/pifs-mount
They serve completely different purposes.
~/pifs-meta
contains the physical metadata representation.
~/pifs-mount
is where applications see the virtual πfs filesystem.
23. Mount πfs
From the source tree:
./src/πfs \
-o mdd="$HOME/pifs-meta" \
"$HOME/pifs-mount"
Code language: JavaScript (javascript)
If installed globally:
πfs \
-o mdd="$HOME/pifs-meta" \
"$HOME/pifs-mount"
Code language: JavaScript (javascript)
The canonical syntax from the project is:
πfs -o mdd=<metadata-directory> <mountpoint>
Code language: HTML, XML (xml)
24. Run πfs in Foreground Mode
For learning and troubleshooting, foreground mode is better:
./src/πfs \
-f \
-o mdd="$HOME/pifs-meta" \
"$HOME/pifs-mount"
Code language: JavaScript (javascript)
Keep that terminal open.
Then use another terminal for experiments.
25. Enable FUSE Debugging
For a particularly instructive demo:
./src/πfs \
-d \
-o mdd="$HOME/pifs-meta" \
"$HOME/pifs-mount"
Code language: JavaScript (javascript)
FUSE’s debug mode shows filesystem activity while applications interact with the mount.
Try another terminal:
ls ~/pifs-mount
and watch requests arrive.
This is one of the best ways to understand the relationship between applications, the kernel, FUSE and filesystem callbacks.
26. Your First File
Create a tiny file:
printf 'Hello' > ~/pifs-mount/hello.txt
Code language: JavaScript (javascript)
Read it:
cat ~/pifs-mount/hello.txt
Code language: JavaScript (javascript)
Expected logical result:
Hello
Check its logical size:
wc -c ~/pifs-mount/hello.txt
Code language: JavaScript (javascript)
Then inspect the physical metadata:
ls -l ~/pifs-meta/hello.txt
Code language: JavaScript (javascript)
and:
xxd ~/pifs-meta/hello.txt
Code language: JavaScript (javascript)
You are not looking at:
48 65 6c 6c 6f
—the ordinary byte representation of Hello.
Instead you are looking at the indexes πfs recorded for those bytes.
That is πfs in action.
27. A Better Experiment
Create:
printf 'AAAAAA' > ~/pifs-mount/a.txt
Code language: JavaScript (javascript)
Then examine:
xxd ~/pifs-meta/a.txt
Code language: JavaScript (javascript)
Because the implementation always begins searching from position zero, identical input bytes should resolve to the same first matching offset.
Therefore repeated characters generate repeated metadata indexes.
Now compare with:
printf 'ABCDEF' > ~/pifs-mount/b.txt
Code language: JavaScript (javascript)
and:
xxd ~/pifs-meta/b.txt
Code language: JavaScript (javascript)
This gives you a simple visual demonstration of how the representation works.
28. Verify πfs Is Really Recomputing Data
Read your file:
cat ~/pifs-mount/hello.txt
Code language: JavaScript (javascript)
The underlying metadata file does not contain the literal string:
Hello
πfs instead:
- reads an index,
- calls
get_byte(index), - calculates π digits using BBP,
- reconstructs the byte,
- returns it through FUSE.
This behavior is directly visible in pifs_read().
29. Create Directories
Because πfs exposes normal filesystem operations, try:
mkdir ~/pifs-mount/demo
Code language: JavaScript (javascript)
Then:
echo test > ~/pifs-mount/demo/test.txt
Code language: JavaScript (javascript)
List it:
find ~/pifs-mount
The directory structure itself is represented inside the metadata directory.
Inspect:
find ~/pifs-meta
This reveals another important concept:
πfs is not generating filenames or directory hierarchy from π.
Those are real metadata stored on your disk.
30. Unmount πfs
On a FUSE 2 environment:
fusermount -u ~/pifs-mount
Alternatively:
umount ~/pifs-mount
may work depending on your environment and privileges.
Before deleting anything, confirm:
mount | grep pifs
or:
findmnt ~/pifs-mount
31. Restart πfs
Your metadata remains in:
~/pifs-meta
Mount it again:
./src/πfs \
-o mdd="$HOME/pifs-meta" \
"$HOME/pifs-mount"
Code language: JavaScript (javascript)
Then:
cat ~/pifs-mount/hello.txt
Code language: JavaScript (javascript)
πfs uses the stored offsets to reconstruct the file again.
32. What Happens If You Delete the Metadata?
Suppose you delete:
~/pifs-meta/hello.txt
Code language: JavaScript (javascript)
Your byte sequence theoretically still exists somewhere in π.
But πfs no longer knows:
where
to retrieve those bytes.
The project README turns this into part of the joke: your files may “still be in π,” but without their positions the useful information has effectively been lost.
Operationally:
The metadata is your data.
Protect it exactly as you would protect the original file.
33. πfs Configuration
πfs itself has almost no configuration.
Its principal custom option is:
mdd
Example:
πfs -o mdd=/srv/pifs-metadata /mnt/pifs
Code language: JavaScript (javascript)
Standard FUSE options may also be processed through libfuse.
Common FUSE-style execution options include:
-f
foreground mode.
-d
debug mode.
-s
single-threaded mode.
A learning-oriented invocation might therefore be:
πfs \
-f \
-s \
-o mdd="$HOME/pifs-meta" \
"$HOME/pifs-mount"
Code language: JavaScript (javascript)
34. allow_other
FUSE normally restricts filesystem access to the user who mounted it.
A FUSE filesystem may support:
-o allow_other
to make the mount accessible to other users.
For unprivileged users, libfuse requires:
user_allow_other
to be enabled in:
/etc/fuse.conf
before allow_other can be used.
For πfs experimentation, there is usually no reason to enable this.
Keep your demo private.
35. Fedora Installation
Fedora continues shipping FUSE 2 compatibility packages.
Install:
sudo dnf install \
git \
gcc \
make \
autoconf \
automake \
pkgconf-pkg-config \
fuse \
fuse-devel
Fedora explicitly describes fuse-devel as the development package for FUSE v2 applications/filesystems.
Then follow the same build procedure:
git clone https://github.com/philipl/pifs.git
cd pifs
./autogen.sh
make
Code language: PHP (php)
36. macOS
Modern libfuse documentation recommends macFUSE for macOS rather than Linux libfuse.
However, πfs itself was written around the Linux/FUSE 2 environment and uses Linux-oriented APIs.
Therefore the easiest path for macOS users is usually:
macOS
↓
Linux VM
↓
Ubuntu 24.04
↓
πfs
Code language: CSS (css)
rather than attempting to modernize the πfs C source for macFUSE.
If your goal is learning πfs rather than porting old filesystem code, a small Linux VM is much less distracting.
37. Windows
πfs does not provide a native Windows implementation.
The practical learning options are:
Linux VM
or potentially a suitable Linux environment with FUSE support.
A conventional VM is the simpler choice because FUSE requires actual filesystem/kernel integration.
38. Containers and πfs
Running FUSE filesystems inside containers is possible but adds additional complexity.
A container typically needs access to:
/dev/fuse
and additional privileges/capabilities.
That means Docker is not necessarily the best first πfs environment.
For learning:
Linux VM > privileged container
because a VM gives the filesystem normal kernel access without weakening a container security boundary.
39. Performance
πfs is extremely slow compared with ordinary filesystems.
The project’s own README famously notes that storing a roughly 400-line text file could take minutes.
There are several reasons.
Reason 1: Byte-by-byte search
Every byte is handled independently.
Reason 2: Search begins from zero
The write implementation loops:
index = 0
index = 1
index = 2
...
until it finds the desired byte.
Reason 3: BBP calculation
Testing each position requires mathematical computation.
Reason 4: Repeated work
If the same byte appears repeatedly, the implementation performs the search again instead of simply consulting a persistent 256-entry mapping.
Reason 5: Userspace filesystem overhead
Each filesystem operation also crosses the kernel/FUSE/userspace boundary.
Performance was never the actual objective.
40. Why a 256-Entry Cache Would Make πfs Much Faster
Because there are only:
256
possible byte values, we could compute:
byte 0x00 -> π index
byte 0x01 -> π index
...
byte 0xFF -> π index
once.
Then writing could become:
index = lookup_table[input_byte]
instead of repeatedly searching π.
That would make the system substantially faster.
But notice what happened.
We now have:
a lookup dictionary
+
an index for every byte
which emphasizes even more clearly that π is not providing magical compression.
The encoding still carries the information.
41. Why Not Store One Bit at a Time?
There are only two possible bits:
0
1
Find one π location containing 0 and one containing 1.
Then every file could be represented as references to those two locations.
Wonderful!
Except your representation is now essentially:
0 -> reference A
1 -> reference B
which is just another representation of:
0
1
You have recreated the original information with more steps.
This thought experiment gets directly to the heart of why πfs is so educational.
42. Is πfs Compression?
Not usefully.
A conventional compressor finds redundancy inside the input.
For example:
AAAAAAAAAAAAAAAA
might become approximately:
"16 copies of A"
Code language: JSON / JSON with Comments (json)
πfs instead replaces symbols with references into a deterministic sequence.
If those references require as much or more information than the original symbols, nothing has been compressed.
πfs is better understood as:
an unusual encoding scheme
rather than:
a practical compression algorithm
43. Is πfs Deduplication?
No.
Deduplication might transform:
Block A
Block B
Block A
Block A
into:
Store:
A
B
References:
A B A A
Repeated data avoids being stored multiple times.
πfs instead relies on a deterministic mathematical sequence that can regenerate values at specified positions.
The underlying ideas are different.
44. Is πfs Content-Addressed Storage?
Not exactly.
Systems such as content-addressed object stores identify data using a cryptographic digest:
content -> hash
and normally store the actual object somewhere.
πfs uses:
content byte -> π offset
and recalculates the byte from π.
There is no conventional backing object containing the original file data.
45. Is πfs Infinite Storage?
No—not in any practical engineering sense.
The phrase is the joke.
The digit expansion of π is mathematically infinite, but πfs still needs:
- metadata storage,
- CPU,
- memory,
- FUSE infrastructure,
- filesystem structures,
- offsets,
- filenames,
- permissions,
- and an executable algorithm.
An infinite mathematical sequence is not equivalent to an infinite usable storage device.
46. Is πfs Lossless?
Within the implementation’s supported operating range and assuming its metadata remains intact, the intent is deterministic byte reconstruction.
That makes its transformation effectively lossless for successfully encoded files.
But πfs is not designed with production-grade durability mechanisms such as:
checksums
replication
journaling guarantees
snapshots
self-healing
distributed redundancy
scrubbing
transactional metadata protection
Code language: PHP (php)
So “lossless mathematical transformation” should not be confused with “reliable storage system.”
47. Metadata Portability
Another implementation detail is worth noticing.
πfs writes:
short
values directly into backing files using the host’s native C representation.
There is no explicit:
portable serialization format
network byte order
versioned metadata schema
Therefore the backing representation should not be treated as a stable cross-platform storage format.
This is another indicator that πfs is a prototype.
48. Filesystem Semantics and Prototype Limitations
The source implements many FUSE callbacks, but it should not be assumed to behave like a mature POSIX filesystem under every condition.
It was built as an experiment.
Examples of areas where production filesystems require far more engineering include:
concurrent access
crash consistency
atomic operations
metadata recovery
locking semantics
rename behavior
security boundaries
ACLs
large files
architecture portability
failure injection
corruption recovery
durability guarantees
πfs should therefore be run on disposable test data.
49. Security
Never interpret the word “metadata” as meaning “non-sensitive.”
πfs metadata is sufficient to reconstruct the logical file.
Therefore:
πfs metadata == sensitive file representation
If someone obtains your metadata and the πfs algorithm, they can reconstruct the data.
πfs provides no inherent:
encryption
access-control architecture
key management
confidentiality mechanism
tamper detection
beyond whatever protection the underlying operating system provides.
Do not store confidential information in πfs experiments.
50. Backup and Disaster Recovery
πfs must never be used as an excuse to avoid backup.
If you wanted to preserve a πfs experiment, the thing you would need to back up is:
metadata directory
+
software/version information
But once you back up the metadata—which is approximately larger than the original file—you have neatly demonstrated the punchline again.
For real storage use technologies designed for backup.
51. Production Use
Do not use πfs for:
- databases,
- Kubernetes PersistentVolumes,
- application state,
- VM disks,
- enterprise files,
- home directories,
- secrets,
- source-code repositories,
- backups,
- archives,
- object storage,
- data lakes,
- logs,
- legal records,
- production workloads.
The project is best understood as:
educational software
+
technical satire
+
filesystem experiment
+
information-theory demonstration
52. Excellent Use Cases for πfs
Despite being unsuitable for production storage, πfs has some genuinely excellent uses.
52.1 Learning FUSE
Study how applications communicate with a userspace filesystem.
52.2 Learning Filesystem APIs
Observe operations such as:
getattr
open
read
write
mkdir
unlink
readdir
fsync
xattr
52.3 Teaching Information Theory
Demonstrate why arbitrary lossless 100% compression cannot exist.
52.4 Teaching Metadata Economics
Show that representing data often moves information somewhere else rather than eliminating it.
52.5 Studying Mathematical Constants
Explore digit extraction and BBP.
52.6 Teaching Encoding vs Compression
πfs provides an unusually memorable example.
52.7 Computer Science Demonstrations
A classroom can combine:
operating systems
filesystems
mathematics
compression
algorithms
data structures
information theory
in one experiment.
52.8 Interview or Engineering Discussion
Ask:
“Could storing a file as an offset into π provide unlimited compression?”
The resulting discussion touches:
- entropy,
- address size,
- search complexity,
- deterministic sequences,
- algorithmic complexity,
- Kolmogorov complexity,
- FUSE,
- representation theory.
That is a surprisingly rich systems-design exercise.
53. Troubleshooting
Error: FUSE development package missing
Typical configure error:
Package requirements (fuse >= 2.8) were not met
Check:
pkg-config --modversion fuse
On Ubuntu 24.04:
sudo apt install libfuse-dev
Do not substitute:
libfuse3-dev
and assume it will compile unchanged.
πfs explicitly targets FUSE 2 APIs.
54. Metadata Directory Error
If you see:
Metadata directory must be specified
you forgot:
-o mdd=...
Correct:
./src/πfs \
-o mdd="$HOME/pifs-meta" \
"$HOME/pifs-mount"
Code language: JavaScript (javascript)
The program explicitly checks for this option during startup.
55. Cannot Access Metadata Directory
πfs checks the metadata directory for:
read
write
execute
access.
Check:
ls -ld ~/pifs-meta
Correct ownership if appropriate:
chown "$USER":"$USER" ~/pifs-meta
Code language: PHP (php)
Do not solve filesystem permission problems with:
chmod 777
unless you specifically understand why it is necessary.
56. Mount Point Does Not Exist
Create it:
mkdir -p ~/pifs-mount
Then mount again.
57. FUSE Device Missing
Check:
ls -l /dev/fuse
And:
lsmod | grep fuse
If appropriate:
sudo modprobe fuse
A restricted container or unusual virtualized environment may not expose /dev/fuse.
58. Files Take Forever to Write
That is expected.
Use tiny files:
printf A > ~/pifs-mount/a
Code language: JavaScript (javascript)
then:
printf Hello > ~/pifs-mount/hello
Code language: JavaScript (javascript)
Do not start your experiment with:
cp ubuntu.iso ~/pifs-mount/
Code language: JavaScript (javascript)
unless your objective is to develop a new appreciation for ordinary storage devices.
59. Debugging a Mount
Run:
./src/πfs \
-d \
-o mdd="$HOME/pifs-meta" \
"$HOME/pifs-mount"
Code language: JavaScript (javascript)
Then from another terminal:
ls ~/pifs-mount
echo A > ~/pifs-mount/a
Code language: JavaScript (javascript)
cat ~/pifs-mount/a
Code language: JavaScript (javascript)
The FUSE request stream makes the internal behavior much easier to understand.
60. A Complete Learning Lab
Here is a compact laboratory exercise.
Step 1 — Build
git clone https://github.com/philipl/pifs.git
cd pifs
./autogen.sh
make
Code language: PHP (php)
Step 2 — Prepare directories
mkdir -p ~/pifs-meta
mkdir -p ~/pifs-mount
Step 3 — Mount
./src/πfs \
-f \
-o mdd="$HOME/pifs-meta" \
"$HOME/pifs-mount"
Code language: JavaScript (javascript)
Step 4 — In another terminal
printf Hello > ~/pifs-mount/hello.txt
Code language: JavaScript (javascript)
Step 5 — Verify
cat ~/pifs-mount/hello.txt
Code language: JavaScript (javascript)
Step 6 — Examine logical representation
xxd ~/pifs-mount/hello.txt
Code language: JavaScript (javascript)
Step 7 — Examine physical metadata
xxd ~/pifs-meta/hello.txt
Code language: JavaScript (javascript)
Step 8 — Compare sizes
wc -c ~/pifs-mount/hello.txt
wc -c ~/pifs-meta/hello.txt
Code language: JavaScript (javascript)
Step 9 — Create repeated data
printf AAAAAA > ~/pifs-mount/repeated.txt
Code language: JavaScript (javascript)
Inspect:
xxd ~/pifs-meta/repeated.txt
Code language: JavaScript (javascript)
Step 10 — Unmount
fusermount -u ~/pifs-mount
This ten-step experiment demonstrates most of πfs’s central ideas.
61. πfs vs Traditional Filesystems
| Property | ext4/XFS | πfs |
|---|---|---|
| Stores file data | Yes | Stores indexes representing bytes |
| Production ready | Yes | No |
| Fast | Yes | No |
| Kernel integration | Native filesystem | FUSE |
| Metadata required | Yes | Yes |
| Compression | Optional | Not practical compression |
| Reliability mechanisms | Mature | Experimental |
| Large files | Normal | Impractical |
| Educational value | Moderate | Extremely high |
| Entertainment value | Respectable | Exceptional |
62. πfs vs Compression
| Property | gzip/zstd | πfs |
|---|---|---|
| Exploits redundancy | Yes | No |
| Practical storage reduction | Often | No |
| Fast decompression | Yes | Comparatively expensive |
| Production use | Yes | No |
| Representation | Compressed stream | π offsets |
| Random input compression | Usually poor | Also poor/worse |
63. πfs vs Deduplication
| Property | Deduplication | πfs |
|---|---|---|
| Stores unique blocks | Yes | No |
| References existing blocks | Yes | References π positions |
| Practical | Yes | No |
| Works well on repeated content | Often | No storage advantage |
| Requires metadata | Yes | Yes |
64. πfs vs Content-Addressed Storage
| Property | CAS | πfs |
|---|---|---|
| Identifier | Usually hash | π position |
| Actual data stored | Yes | Recomputed from π |
| Integrity checking | Usually strong | Not fundamental |
| Distributed usage | Common | No |
| Production systems | Many | Experimental |
65. πfs vs /dev/zero
There is a funny conceptual comparison.
/dev/zero generates:
00 00 00 00 ...
without storing those zero bytes anywhere.
πfs similarly generates values computationally rather than storing their literal values.
The difference is that /dev/zero generates exactly one predictable sequence.
πfs attempts to use a deterministic sequence rich enough to contain arbitrary byte values and saves the instructions needed to select those values.
Again:
The information lives in the selection instructions.
66. The Information-Theory Lesson
The deepest πfs lesson can be written in one sentence:
You cannot eliminate information merely by replacing the information with an equally informative address.
Consider a hypothetical library containing every possible book.
You no longer need to store your book.
Wonderful.
But now you must store:
building
floor
room
shelf
book
page
offset
length
If the library contains an astronomically large number of books, the address may itself become enormous.
πfs is the digital version of that paradox.
67. Kolmogorov Complexity
πfs also connects naturally to Kolmogorov complexity.
Informally, the Kolmogorov complexity of a string is the size of the shortest program capable of producing it.
For something highly structured:
AAAAAAAAAAAAAAAAAAAAAAAAAAAA
a short description exists:
print A 28 times
Code language: PHP (php)
For sufficiently random data, the shortest description may be roughly the data itself.
πfs tries to describe information using:
π algorithm + offsets
but the offsets themselves carry the entropy necessary to identify arbitrary content.
That is why π does not provide a universal escape hatch from compression limits.
68. What Could Be Improved Technically?
If someone wanted to modernize πfs as an educational project, several improvements would be interesting.
FUSE 3 Port
Modernize the callbacks and build system for current libfuse.
Byte Lookup Cache
Precompute the earliest location of every possible byte.
256 entries
would eliminate repeated write searches.
Portable Metadata Format
Replace raw native short storage with explicitly serialized integers.
Checksums
Add integrity verification.
Versioned Metadata
Introduce a header:
magic
version
algorithm
endianness
record size
checksum
Tests
Build unit tests around:
get_byte()
read/write round trip
directories
truncate
rename
xattrs
concurrent operations
Benchmarking
Measure:
write latency
read latency
CPU usage
metadata expansion ratio
operations/sec
The result still would not become a competitive filesystem—but it could become an even better systems-programming laboratory.
69. A More Efficient Educational Design
Because every possible byte has only 256 values, an optimized version could build:
uint16_t byte_to_pi[256];
Code language: CSS (css)
At startup:
scan π
until all 256 byte values have been observed
Then writing becomes:
byte
↓
lookup
↓
uint16 offset
Reading remains:
offset
↓
BBP
↓
byte
This would be dramatically faster while retaining the educational idea.
And it would make the storage paradox even easier to measure:
8-bit byte
↓
16-bit index
Perfectly illustrating negative compression.
70. Why πfs Matters Even Though It Is Not Practical
πfs is valuable because it compresses several important ideas—not files—into one memorable experiment:
Filesystems are abstractions.
What applications see as a file does not necessarily correspond directly to physical disk blocks.
Data can be generated instead of stored.
Virtual filesystems frequently compute their contents dynamically.
Metadata can become more expensive than payload.
A recurring problem in real distributed systems.
Deterministic generation is not automatically compression.
The parameters required to regenerate arbitrary information still carry information.
Infinite mathematical structures do not imply infinite practical resources.
Computation, addressing and representation all have costs.
“Where is the data?” is sometimes the wrong question.
Often the real question is:
“What information must I retain to reconstruct the data?”
71. Current Project Status in 2026
The original πfs repository remains publicly available under the GPL-3.0 family of licensing and still contains the original C/FUSE implementation. Its README now prominently directs readers toward InferenceFS for the “latest in data-free filesystems.”
πfs itself remains fundamentally the original experimental concept.
Do not interpret renewed online interest or repository popularity as evidence of production maturity.
Its value lies primarily in:
education
experimentation
humor
computer science
filesystem engineering
information theory
72. What Is InferenceFS?
The same author has created a modern successor called:
InferenceFS
The joke has evolved.
πfs says:
Your file already exists inside π.
I only need to remember where.
InferenceFS says, roughly:
Why even remember where?
Give an LLM the filename and ask it what the file probably contained.
The successor uses language-model backends and describes itself as storing essentially filenames while generating plausible contents when files are accessed.
The comparison is delightfully revealing:
| Concept | πfs | InferenceFS |
|---|---|---|
| “Data source” | π | LLM |
| Persistent information | π indexes | Primarily filenames/metadata |
| Reconstruction | Deterministic mathematics | Model inference |
| Exact original content | Intended | Not generally |
| Core joke | Infinite mathematical storage | AI as lossy memory |
| Real lesson | Information theory | Generative models and lossy representation |
InferenceFS should be studied separately because its semantics are fundamentally different from lossless storage.
73. Recommended Learning Path
For engineers wanting to study πfs properly:
Level 1 — Concept
Understand:
π
normal numbers
hexadecimal
bytes
FUSE
Level 2 — Run It
Build and mount πfs.
Level 3 — Observe It
Use:
-d
xxd
strace
findmnt
to observe filesystem behavior.
Level 4 — Read the Source
Start with:
pifs_write()
pifs_read()
get_byte()
Level 5 — Understand BBP
Study arbitrary-position hexadecimal digit calculation.
Level 6 — Information Theory
Study:
entropy
pigeonhole principle
lossless compression limits
Kolmogorov complexity
Level 7 — Modify πfs
Implement:
256-byte lookup cache
portable metadata
metrics
tests
FUSE 3 port
At that point πfs turns from a joke into a very effective systems-programming exercise.
74. Useful Commands Cheat Sheet
Build:
git clone https://github.com/philipl/pifs.git
cd pifs
./autogen.sh
make
Code language: PHP (php)
Prepare:
mkdir -p ~/pifs-meta ~/pifs-mount
Code language: JavaScript (javascript)
Mount:
./src/πfs \
-o mdd="$HOME/pifs-meta" \
"$HOME/pifs-mount"
Code language: JavaScript (javascript)
Foreground:
./src/πfs \
-f \
-o mdd="$HOME/pifs-meta" \
"$HOME/pifs-mount"
Code language: JavaScript (javascript)
Debug:
./src/πfs \
-d \
-o mdd="$HOME/pifs-meta" \
"$HOME/pifs-mount"
Code language: JavaScript (javascript)
Create:
printf Hello > ~/pifs-mount/hello.txt
Code language: JavaScript (javascript)
Read:
cat ~/pifs-mount/hello.txt
Code language: JavaScript (javascript)
Inspect metadata:
xxd ~/pifs-meta/hello.txt
Code language: JavaScript (javascript)
Compare:
wc -c ~/pifs-mount/hello.txt
wc -c ~/pifs-meta/hello.txt
Code language: JavaScript (javascript)
Unmount:
fusermount -u ~/pifs-mount
75. Frequently Asked Questions
Does π contain every file ever created?
That has not been mathematically proven.
The idea depends on π possessing sufficiently strong digit-distribution properties, commonly discussed in terms of normality.
Does πfs really work?
Yes, as an experimental FUSE implementation.
It maps bytes to positions generated from π and reconstructs them during reads.
Does πfs provide infinite free storage?
No.
It consumes metadata storage and significant computation.
Does πfs actually compress files?
Not practically.
The original implementation typically stores a two-byte position for every one-byte input value.
Does πfs store the original byte?
Not directly in its metadata representation.
It stores a position used to regenerate that byte from π.
What happens if metadata is lost?
The logical file is effectively lost because its selected π locations are no longer known.
Is BBP a search algorithm?
No.
BBP allows digits near a specified position to be calculated efficiently relative to generating every preceding digit.
Finding where arbitrary content occurs remains a separate problem.
Is πfs production ready?
No.
It is an experimental and educational project.
Can I store terabytes in πfs?
In theory you can ask many strange things of computers.
In practice, do not do this.
Can I use πfs for backups?
Absolutely not.
The metadata is effectively an encoding of your data and itself must be protected.
Why use πfs at all?
Because few projects teach so many concepts simultaneously while being this entertaining.
76. Final Takeaway
πfs begins with an irresistible proposition:
If every finite sequence exists somewhere inside π, why store data at all?
Then reality arrives.
You need to discover where the data occurs.
You need to remember those locations.
Those locations themselves contain information.
Searching costs computation.
The metadata consumes storage.
And in the original implementation, representing one byte typically requires about two bytes of stored position information.
The supposedly “data-free” filesystem therefore teaches something much more valuable than a storage trick:
Information cannot be wished away.
You may compress it.
You may encode it.
You may reference it.
You may derive it.
You may regenerate it.
You may move it from payload into metadata.
But for arbitrary lossless information, somewhere in the system enough information must still exist to distinguish the original data from every other possible data set.
That makes πfs more than an April-Fools-style filesystem.
It is a compact laboratory for understanding:
- filesystems,
- FUSE,
- hexadecimal representation,
- mathematical constants,
- random access algorithms,
- metadata,
- compression,
- entropy,
- information theory,
- and the difference between a clever representation and genuinely reduced information.
And that is why, more than a decade after it appeared, πfs remains one of the most memorable filesystem experiments you can compile.
References and Further Study
The authoritative starting point is the original philipl/pifs repository and its source implementation.
For understanding the userspace filesystem architecture underlying πfs, refer to the current libfuse project and API documentation.
For modern Linux packaging, Ubuntu continues to publish the FUSE 2 development libraries while modern libfuse itself is firmly in the FUSE 3 generation.
For the project’s modern spiritual successor, see InferenceFS, which takes the “data-free filesystem” joke into the LLM era.
I’m Rajesh Kumar, a DevOps, SRE, DevSecOps, Cloud, and Platform Engineering expert passionate about sharing practical knowledge, real-world experiences, and industry best practices. I have worked at Cotocus and regularly write about technology, travel, investing, health, product reviews, and digital marketing through my various platforms.
I publish technical articles at DevOps School, travel stories at Holiday Landmark, stock market insights at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow, and SEO and digital marketing strategies at Wizbrand.
Find Trusted Cardiac Hospitals
Compare heart hospitals by city and services — all in one place.
Explore Hospitals