Real-time file system monitoring is essential for security auditing, configuration management, and application observability on Linux servers. Three primary kernel interfaces enable file event monitoring: fanotify, inotify, and the Go-native fsnotify library. This guide compares these monitoring approaches, their use cases, and how to deploy self-hosted file monitoring solutions.
Why Linux File System Monitoring Matters
Linux servers generate constant file system activity — configuration changes, log writes, application deployments, and potential unauthorized modifications. Without real-time monitoring, you discover problems only during periodic audits or when they cause visible failures.
File system monitoring enables:
- Security auditing — Detect unauthorized file modifications, rootkit installations, and configuration drift
- Configuration management — Trigger automatic reloads when config files change
- Application observability — Monitor file access patterns for performance analysis
- Compliance tracking — Maintain audit trails for regulatory requirements
For broader Linux security auditing, see our server security comparison and file integrity monitoring guide.
fanotify: File Access Notification System
fanotify (file access notification) is a modern Linux kernel interface introduced in kernel 2.6.37 that provides file system event monitoring at the file level (not directory level like inotify). It is designed for security and anti-virus applications that need to monitor file access across the entire file system.
Key Features
- File-level monitoring — Monitor individual files, not just directories
- Filesystem-wide events — Watch all files on a mounted filesystem, not just specific paths
- Permission decisions — Block or allow file operations in real time (FAN_RESPONSE)
- File descriptor access — Receive an open file descriptor with each event for content inspection
- Fan groups — Create multiple independent monitoring groups with different rules
- Mark types — Support for mount marks, filesystem marks, and directory marks
Kernel Interface
fanotify is accessed via the fanotify_init() and fanotify_mark() system calls:
| |
User-Space Tools
Several user-space tools leverage fanotify for practical file monitoring:
| |
Docker Deployment
| |
When to Use fanotify
- System-wide file access monitoring — Track all file opens, reads, and writes
- Security and anti-virus scanning — Inspect files before they are executed
- File operation blocking — Prevent unauthorized file modifications in real time
- Mount-level monitoring — Watch entire filesystems without enumerating directories
inotify: Inode-Based File Notification
inotify (inode notify) is the original Linux file notification interface, available since kernel 2.6.13. It monitors specific directories and files for events like modifications, creations, deletions, and attribute changes.
Key Features
- Directory-level monitoring — Watch specific directories and their contents
- Granular event types — Access, modify, create, delete, move, close, open, and attribute changes
- Recursive watching — Monitor directory trees (with limitations)
- Well-established ecosystem — Widely supported by user-space tools and libraries
- Resource limits — Controlled via
fs.inotify.max_user_watchessysctl
User-Space Tools
| |
SystemD Integration
| |
| |
Docker Compose for inotify-Based Monitoring
| |
When to Use inotify
- Directory-specific monitoring — Watch known configuration directories
- Application config reloads — Trigger service restarts when configs change
- Build system integration — Rebuild or reprocess when source files change
- Limited resource environments — Lower overhead than fanotify for targeted monitoring
fsnotify: Go-Native Cross-Platform File Watching
fsnotify (github.com/fsnotify/fsnotify) is the de facto standard Go library for cross-platform file system notification. It wraps inotify on Linux, FSEvents on macOS, and ReadDirectoryChangesW on Windows, providing a unified API.
Key Features
- Cross-platform — Single API works on Linux, macOS, Windows, and BSD
- Go-native — No CGo dependencies, pure Go implementation
- Event channel API — Events delivered via Go channels for concurrent processing
- Recursive watching — Add watchers for subdirectories dynamically
- Widely adopted — Used by Hugo, Docker, Kubernetes, and many other Go projects
Go Example
| |
When to Use fsnotify
- Go application development — Native file watching in Go services
- Cross-platform tools — Single codebase for Linux, macOS, and Windows
- Build tools and dev servers — Hugo uses fsnotify for live reload
- Lightweight monitoring — Simple event processing without kernel-level features
Comparison Table
| Feature | fanotify | inotify | fsnotify |
|---|---|---|---|
| Kernel Interface | fanotify (2.6.37+) | inotify (2.6.13+) | Wraps inotify (Linux) |
| Monitoring Scope | Filesystem-wide | Directory-specific | Directory-specific |
| File Descriptor Access | Yes (open fd with events) | No | No |
| Permission Blocking | Yes (FAN_RESPONSE) | No | No |
| Cross-Platform | Linux only | Linux only | Linux, macOS, Windows, BSD |
| Recursive Watching | Yes (filesystem mark) | Manual per-directory | Manual per-directory |
| Resource Limits | No hard limit | max_user_watches sysctl | Limited by inotify |
| Security Use Cases | Anti-virus, auditing | Config monitoring | App-level watching |
| Language Support | C, Python wrappers | C, CLI tools, Python | Go |
| Best For | System-wide security | Config reloads, auditing | Go applications, dev tools |
Choosing the Right Approach
For Security Auditing
Use fanotify for comprehensive file access monitoring across the entire filesystem. Its file descriptor access and permission blocking capabilities make it suitable for security-sensitive environments.
For Configuration Management
Use inotify (via inotify-tools or systemd.path) for monitoring specific configuration directories. It is lightweight, well-understood, and integrates cleanly with system services.
For Go Application Development
Use fsnotify for cross-platform file watching in Go applications. Its channel-based API integrates naturally with Go’s concurrency model.
Recommended Monitoring Architecture
| |
Why Self-Host File Monitoring?
Running file monitoring on your own Linux servers ensures complete visibility into file system activity, avoids sending sensitive file paths to external services, and integrates directly with local security tools. For compliance-driven environments, self-hosted monitoring keeps audit trails under your control and enables real-time response to unauthorized changes.
For Linux system administration tooling, our systemd timer management guide covers scheduling periodic file integrity checks. Teams managing Linux security should also review our SELinux management comparison for mandatory access control enforcement.
FAQ
What is the difference between fanotify and inotify?
fanotify monitors at the file level across entire filesystems and can provide open file descriptors with events, enabling content inspection and permission decisions. inotify monitors specific directories and files, providing event notifications without file access. fanotify is designed for security applications; inotify is designed for application-level file watching.
Can fanotify monitor all files on a system without impacting performance?
fanotify’s filesystem-wide monitoring does introduce overhead proportional to file access volume. For high-throughput systems, filtering events (e.g., only monitoring specific file types or excluding high-churn directories like /tmp) is recommended. The FAN_REPORT_FID flag reduces overhead by reporting file handles instead of paths.
How many files can inotify watch simultaneously?
The default limit is typically 8,192 watches, controlled by fs.inotify.max_user_watches. For monitoring large directory trees, increase this value: sysctl fs.inotify.max_user_watches=524288. Each watch consumes approximately 1KB of kernel memory.
Does fsnotify work on Linux kernels older than 2.6.13?
No. fsnotify wraps inotify on Linux, which requires kernel 2.6.13 or later. All modern Linux distributions ship with kernels far newer than this (5.x or 6.x series), so compatibility is not a concern for current systems.
How do I make file monitoring survive system reboots?
For inotify-based monitoring, use systemd.path units which are managed by systemd and automatically restart on boot. For fanotify tools, create a systemd service unit with Restart=always. For fsnotify-based Go applications, run them as systemd services or in Docker containers with restart policies.
Can I use these tools to monitor Docker container file systems?
Yes, but with caveats. inotify and fanotify work on the host filesystem, so you can monitor Docker volume mount points. For monitoring inside containers, install inotify-tools within the container image. Note that overlay filesystems may have limitations with inotify event delivery for some operations.