fspy (1) : Trace Filesystem Activity and I/O Patterns in Your Linux Applications (1)
Have you ever wondered which files your application is reading and writing behind the scenes? Or tried to figure out why a program is slow — only to suspect it might be hammering the same files over and over? Linux gives us powerful tools for tracing system calls (strace) and profiling CPU usage, but tracing filesystem activity at the file level in a simple, readable way is surprisingly underserved.
That’s where fspy comes in.
What is fspy?
fspy is a lightweight Linux command-line tool that monitors filesystem events in real time — file opens, reads, writes, creates, deletes, and more. It tells you exactly what files your application is touching, how much data is being written, and (with root access) which process triggered each event.
It sits somewhere between inotifywait (which is raw and hard to read) and strace (which is powerful but overwhelming). fspy is designed to be immediately useful without needing to parse thousands of system call lines.
fspy uses two Linux kernel APIs internally:
- inotify — the default mode. Fast, low overhead, works without root. Watches specific paths you give it.
- fanotify (with
-Pflag) — process tracking mode. Requires root. Monitors an entire filesystem mount point and shows you which process (PID, UID, command name) triggered each event.
Installing fspy
fspy is available in Debian/Ubuntu:
sudo apt install fspy
Or build from source:
git clone https://salsa.debian.org/debian/fspy.git
cd fspy
make
sudo make install
Basic Usage
fspy [options] <path>
The simplest invocation — watch a directory:
fspy /tmp
You’ll immediately see every filesystem event on /tmp:
[Sun Feb 22 14:01:12 2026] CREATE:/tmp/myapp_cache
[Sun Feb 22 14:01:12 2026] OPEN:/tmp/myapp_cache
[Sun Feb 22 14:01:12 2026] WRITE:/tmp/myapp_cache
[Sun Feb 22 14:01:12 2026] CLOSE_W:/tmp/myapp_cache
Press Ctrl+C to stop.
Key Options
| Option | Description |
|---|---|
-F REGEX |
Filter events by filename (only show matching paths) |
-I REGEX |
Inverted filter (exclude matching paths) |
-T TYPE |
Filter by file type:f=file, d=dir, s=symlink, etc. |
-R DEPTH |
Watch subdirectories recursively up to DEPTH levels |
-O FORMAT |
Customize output format |
-P |
Show which process triggered each event (requires root) |
-B |
Show I/O size per event (write size in inotify, read+write in fanotify) |
-W |
Show file temperature summary at exit — HOT/WARM/COLD (implies -B) |
Practical Examples
1. Watch a specific application’s work directory
fspy -R 3 /var/lib/myapp
Watches /var/lib/myapp and up to 3 levels of subdirectories.
2. Filter for log files only
fspy -F '\.log$' /var/log
Only shows events for files ending in .log. Ignore all the noise.
3. Watch config files for unexpected changes
fspy -T f -F '\.conf$' /etc
Useful for detecting when a service silently rewrites its config, or when a poorly behaved package manager touches files it shouldn’t.
4. Exclude noisy files
fspy -F '\.db$' -I 'journal|wal' /var/lib/myapp
Show database files but exclude journal and WAL files (common with SQLite).
5. Custom output format
fspy -O 'T, - ,d,:,p,f' /tmp
Produces output like:
Sun Feb 22 14:05:31 2026 - WRITE:/tmp/app_output.log
The -O format is a comma-separated list of fields: T=timestamp, d=event type, p=path, f=filename, s=file size, and more.
Process Tracking with -P
This is fspy’s most powerful feature. Run it as root and it tells you which application is responsible for each filesystem event:
sudo fspy -P /var/log
Output:
[Sun Feb 22 14:10:22 2026] WRITE:/var/log/syslog [PID:312 UID:104 CMD:rsyslogd]
[Sun Feb 22 14:10:22 2026] OPEN:/var/log/auth.log [PID:1847 UID:0 CMD:sudo]
[Sun Feb 22 14:10:23 2026] READ:/var/log/syslog [PID:5021 UID:1000 CMD:tail -f /var/log/syslog]
This is invaluable for debugging:
- “Why is my disk busy at 3am?” → run
sudo fspy -P /and find out which process is writing - “Is my application caching properly or re-reading the same file constantly?” → watch it with
-P - “Which service keeps touching this config file?” → instant answer
In fanotify mode (-P), fspy monitors the entire mount point automatically, so you don’t need to specify every subdirectory.
I/O Size Tracking with -B
The -B flag adds per-event I/O size information to each line.
fspy -B /tmp
[Sun Feb 22 14:15:44 2026] WRITE:/tmp/output.bin [write:+1.0MB]
[Sun Feb 22 14:15:44 2026] WRITE:/tmp/output.bin [write:+1.0MB]
[Sun Feb 22 14:15:44 2026] WRITE:/tmp/output.bin [write:+512.0KB]
[Sun Feb 22 14:15:45 2026] WRITE:/tmp/output.bin [write:+12B]
This works by comparing the file size before and after each write event. It’s great for spotting:
- Small, frequent writes that could be batched (terrible for performance)
- Large sequential writes (usually fine)
- Unexpectedly large writes to temporary files
With -P and -B combined (fanotify mode), fspy reads /proc/PID/io to get both read and write deltas per process:
sudo fspy -P -B /var/lib/postgresql
[Sun Feb 22 14:20:11 2026] WRITE:/var/lib/postgresql/data/pg_wal/000001 [PID:3421 UID:999 CMD:postgres] [read:0B write:+8.0KB]
[Sun Feb 22 14:20:11 2026] READ:/var/lib/postgresql/data/base/16384/1259 [PID:3421 UID:999 CMD:postgres] [read:+8.0KB write:0B]
File Temperature Summary with -W
This is fspy’s unique I/O profiling feature. The -W flag (implies -B) accumulates total I/O per file throughout your monitoring session, then prints a heat map when you press Ctrl+C:
fspy -W /var/lib/myapp
After a few minutes of normal application activity, press Ctrl+C:
fspy: stopping tracing...
=== File I/O Temperature Summary ===
TEMP TOTAL-READ TOTAL-WRITE COUNT PATH
----- ---------- ----------- ----- ----
[HOT ] 0B 45.3MB 128 /var/lib/myapp/events.log
[HOT ] 12.1MB 8.7MB 89 /var/lib/myapp/cache.db
[WARM] 1.2MB 800.0KB 34 /var/lib/myapp/sessions/active.db
[COLD] 0B 2.1KB 3 /var/lib/myapp/config.json
=====================================
Temperature thresholds:
- HOT — more than 10MB total I/O
- WARM — more than 1MB total I/O
- COLD — everything else
This summary immediately tells you:
- Which files are your application’s real I/O bottlenecks
- Which files are worth caching in memory
- Which “cold” config files could be read once and cached rather than re-read repeatedly
Real-World Debugging Scenarios
Scenario 1: “My web app is slow under load”
sudo fspy -P -W -F '\.db$|\.log$' /var/lib/myapp
Let it run during a load test, then Ctrl+C. The temperature summary shows you exactly which database files and log files are your hot spots — and which process is responsible.
Scenario 2: “Something keeps creating temp files and not cleaning them up”
fspy -T f -F '/tmp/' -R 2 /tmp
Watch for CREATE events with no corresponding DELETE. You’ll quickly spot the culprit file pattern.
Scenario 3: “Is my application re-reading config on every request?”
sudo fspy -P -F 'config\.json' /etc/myapp
If you see repeated OPEN+READ events for the same config file for every request, your app is not caching its config — an easy performance win.
Scenario 4: “Identify hot files before adding a caching layer”
fspy -W -R 3 /var/lib/myapp
Run during peak usage. The HOT files in the summary are your best candidates to serve from memory cache (Redis, memcached, or even a simple in-process LRU cache).
Why fspy Instead of strace or lsof?
| Tool | Strength | Weakness for this use case |
|---|---|---|
strace |
Captures every syscall | Overwhelming output, significant overhead, hard to see file-level patterns |
lsof |
Shows open files at a moment in time | Not real-time, no event history, no I/O sizes |
inotifywait |
Raw inotify events | No process info, no I/O sizes, harder to filter |
auditd |
Comprehensive security auditing | Complex to configure, not developer-friendly |
| fspy | File-level events with I/O sizes and process info | Focused on filesystem activity (not all syscalls) |
fspy is not trying to replace strace for deep debugging. It fills the gap between “I want to know what files are being touched” and “I need to audit every system call.” For the common case of understanding your application’s filesystem behaviour, fspy gives you the answer in seconds.
Summary
fspy is a practical tool for any Linux developer or system administrator who wants to understand filesystem activity at a glance. Whether you’re:
- Debugging a slow application
- Hunting down unexpected file modifications
- Identifying I/O hot spots before optimizing
- Understanding what a third-party service is doing to your filesystem
…fspy gives you a clear, readable view without the noise of lower-level tracing tools.
The combination of -P (process tracking) and -W (temperature summary) makes it especially useful as a quick profiling step before committing to a more invasive optimization effort.
Source code and packaging: https://salsa.debian.org/debian/fspy
fspy is available in Debian unstable and maintained by Bean Huo. Bug reports and contributions welcome via the Salsa repository.


