Monitoring filesystem events on Linux servers is essential for automation workflows — triggering actions when files arrive, detecting configuration changes, and reacting to directory updates. Three primary approaches handle this task: systemd.path (native systemd path units), inotifywait (the inotify-tools CLI utility), and incron (inotify-based cron daemon).
Each method has different strengths in configuration complexity, event granularity, daemon requirements, and integration with existing system management. This guide compares all three with real configurations for common server automation scenarios.
The Filesystem Monitoring Problem
Server automation often requires reacting to filesystem events:
- Process files dropped into an import directory
- Reload configuration when files change
- Trigger backups when specific directories are modified
- Archive logs when they reach a certain size
- Synchronize directories across servers
The traditional approach — polling with cron — wastes resources and introduces latency. Event-driven monitoring reacts instantly and consumes minimal CPU.
systemd.path: Native Path Unit Monitoring
systemd.path units monitor files and directories using the kernel’s inotify mechanism, all managed through systemd’s unified unit system. When a path change is detected, systemd can activate a corresponding service unit.
Key Features
- No separate daemon — managed entirely by systemd
- Unit-based lifecycle — start, stop, enable, disable like any systemd unit
- Multiple trigger types — PathExists, PathChanged, PathModified, DirectoryNotEmpty
- Service activation — automatically starts a paired service unit on event
- Dependency integration — full systemd dependency and ordering support
- Credential support — can pass credentials to triggered services
Path Unit Configuration
| |
Corresponding Service Unit
| |
Processing Script Example
| |
Enabling and Managing
| |
PathExists vs PathChanged vs PathModified
| |
When to Use systemd.path
systemd.path is the best choice for simple file/directory monitoring that triggers systemd services. Its zero-daemon overhead and tight systemd integration make it ideal for server automation tasks.
Best for: Drop-directory processing, configuration change detection, simple event-driven service activation.
Limitations: Limited to activating systemd services — cannot run arbitrary inline commands. Less granular event types than raw inotify.
inotifywait: The Flexible CLI Monitor
inotifywait (part of inotify-tools) provides a command-line interface to the Linux inotify subsystem. It watches files and directories and reports events in real time, making it ideal for scripting and pipeline integration.
Key Features
- Real-time event streaming — outputs events as they occur
- Granular event types — create, modify, delete, move, access, open, close, and more
- Recursive monitoring — watch entire directory trees with
-r - Format control — customizable output format with
--format - Pipeline-friendly — designed to work with shell pipelines and loops
- No daemon required — run as a foreground process or background job
Docker Compose Integration
| |
inotifywait Monitoring Script
| |
Monitoring Configuration Reload
| |
Event Types Reference
| Event | Description |
|---|---|
access | File was read |
modify | File content was written to |
attrib | File metadata changed (permissions, timestamps) |
close_write | File opened for writing was closed |
close_nowrite | File opened read-only was closed |
create | File/directory created in watched directory |
delete | File/directory deleted from watched directory |
moved_from | File/directory moved out of watched directory |
moved_to | File/directory moved into watched directory |
isdir | Event occurred on a directory |
When to Use inotifywait
inotifywait is ideal for complex event handling that requires custom scripting logic, event filtering, or pipeline integration. Its real-time streaming model and granular event types give you fine-grained control over event reactions.
Best for: Custom event processing pipelines, complex filtering logic, directory synchronization triggers, real-time log monitoring.
Limitations: Requires a running process (daemon or background job). No built-in service management — you handle process lifecycle yourself. Recursive monitoring can miss newly created subdirectories.
incron: The Inotify Cron Daemon
incron (inotify cron) combines inotify event monitoring with cron-like syntax. You define watch rules in a table file, and the incron daemon triggers commands when matching events occur.
Key Features
- Cron-like syntax — familiar table-based configuration
- Event-to-command mapping — each watch rule maps to a specific command
- User-level tables — each user has their own incrontab
- Daemon managed — incron runs as a background daemon
- Variable substitution —
$@(watched path),$#(event file),$%(event mask) - Lightweight — minimal resource overhead
incrontab Configuration
| |
Enabling incron
| |
Sync Script Example
| |
When to Use incron
incron is the right choice when you want cron-like simplicity for filesystem events. Its table-based configuration is easy to manage, and the daemon handles all the complexity of inotify monitoring.
Best for: Simple event-to-command mappings, directory synchronization triggers, configuration reload automation.
Limitations: Less flexible than inotifywait for complex event processing. No built-in debouncing — rapid events can trigger duplicate commands. Debugging can be difficult since commands run silently in the background.
Head-to-Head Comparison
| Feature | systemd.path | inotifywait | incron |
|---|---|---|---|
| Daemon Required | No (systemd) | No (CLI process) | Yes (incrond) |
| Configuration | Unit files | Shell scripts | incrontab table |
| Event Granularity | 4 types | 15+ event types | 8 event types |
| Recursive Watch | No (single path) | Yes (-r flag) | No (single path) |
| Service Integration | Full systemd | Manual | Manual |
| Debouncing | Built-in | Manual (sleep) | Manual |
| User Permissions | System-level | Any user | User tables |
| Variable Access | Via service env | Full shell access | $@, $#, $% |
| Process Management | systemd handles it | You manage it | incrond handles it |
| Best For | Simple service triggers | Complex pipelines | Cron-like rules |
Common Use Cases and Recommended Approach
Drop Directory Processing
For processing files dropped into an import directory:
| |
Configuration Change Detection
For reloading services when config files change:
| |
Directory Synchronization
For keeping directories in sync:
| |
Why Self-Host Your Filesystem Monitoring?
Self-hosting filesystem event monitoring gives you complete control over automation triggers, response timing, and error handling. Unlike cloud-based file monitoring services that introduce latency and dependency on external infrastructure, local event monitoring reacts instantly and works offline.
For teams managing self-hosted infrastructure — from homelab automation to enterprise server management — event-driven file monitoring eliminates the polling overhead of cron and enables real-time reactions to filesystem changes.
For systemd management tools, see our systemd timer management guide. For log monitoring, check our log forwarding with Fluent Bit and Vector guide. For Linux system administration, our Linux service restart detection guide covers service lifecycle management.
FAQ
Which filesystem monitoring method should I choose?
Use systemd.path for simple directory monitoring that triggers systemd services — it requires no additional packages and integrates natively. Use inotifywait for complex event processing with custom scripting logic and granular event filtering. Use incron for cron-like event-to-command mappings where you prefer table-based configuration.
Can systemd.path monitor multiple paths?
Yes. A single systemd.path unit can include multiple PathChanged=, PathModified=, PathExists=, and DirectoryNotEmpty= lines. All monitored paths trigger the same associated service unit.
Does inotifywait support recursive directory watching?
Yes, with the -r flag. However, inotifywait does not automatically watch newly created subdirectories during a recursive watch. For reliable recursive monitoring, consider using a polling fallback or restarting the watch when new directories appear.
How do I prevent incron from firing duplicate commands?
incron does not have built-in debouncing. To prevent duplicate triggers, use a lock file in your command script:
| |
Can I monitor network filesystems (NFS, CIFS) with these tools?
inotify and therefore all three methods work best on local filesystems (ext4, XFS, Btrfs). NFS and CIFS may not support all inotify events reliably. For network filesystem monitoring, consider polling-based alternatives or filesystem-specific monitoring tools.
Frequently Asked Questions
What happens if the triggered service fails?
For systemd.path, the service failure is tracked by systemd and visible in systemctl status. For inotifywait, the background process handles errors according to your script logic. For incron, command failures are logged to syslog but not automatically retried.
Do these methods survive system reboots?
systemd.path and incron units/services are persistent — enabled units and incrontab entries survive reboots. inotifywait processes must be managed by systemd, supervisord, or another process manager to restart after reboot.
How much CPU does filesystem monitoring consume?
All three methods use the kernel’s inotify subsystem, which has near-zero CPU overhead when idle. CPU usage only increases when events occur and your processing logic runs. This is dramatically more efficient than polling-based approaches like while true; do ls; sleep 1; done.
Choosing the Right Filesystem Monitoring Tool
The right choice depends on your operational requirements:
- Use systemd.path for reliable, daemon-free monitoring that triggers systemd services — ideal for drop-directory processing and configuration reload automation.
- Use inotifywait when you need granular event types, recursive directory watching, or complex scripting logic with pipeline integration.
- Use incron for simple event-to-command mappings where cron-like table configuration is preferred over writing shell scripts or unit files.
For most server automation tasks, systemd.path provides the best combination of simplicity and reliability. When you need more control over event processing, inotifywait gives you the flexibility to build any monitoring pipeline you need.