lsyncd — quick reference
One-shot CLI (testing)
Quick rsync-over-inotify tests without a config file — good for lab validation.
| When to use | Command |
|---|---|
| Show lsyncd version | lsyncd --version |
| Sync two local dirs (daemon mode) | lsyncd -rsync /source/ /target/ |
| Foreground mode with live log lines | lsyncd -nodaemon -rsync /source/ /target/ |
| Sync to remote host via rsync | lsyncd -nodaemon -rsync /source/ host:/target/ |
| Remote sync with SSH for moves/deletes | lsyncd -nodaemon -rsyncssh /source host /target/ |
Trailing slashes on source matter — /source/ syncs contents; /source may sync the directory node differently.
Global settings (/etc/lsyncd.conf)
| When to use | Setting |
|---|---|
| Log file path | logfile = "/var/log/lsyncd/lsyncd.log" |
| Periodic status snapshot | statusFile = "/var/log/lsyncd-status.log" |
| Status write interval (seconds) | statusInterval = 20 |
| Stay in foreground (debug) | nodaemon = true |
| Max open inotify watches | maxProcesses = 1 (default varies) |
Sync blocks — local
| When to use | Directive |
|---|---|
| Local mirror with rsync at startup, cp/rm/mv live | default.direct |
| Local mirror using rsync for all events | default.rsync |
| Source directory (absolute path) | source = "/source" |
| Target directory (absolute path) | target = "/target" |
| Batch delay before sync (seconds) | delay = 10 |
| Do not delete extra files on target | delete = false |
| Exclude patterns inline | exclude = { 'file*', '*tmp' } |
| Exclude from file (rsync-style) | excludeFrom = "/etc/lsyncd.exclude" |
Sync blocks — remote
| When to use | Directive |
|---|---|
| Remote rsync target | target = "host:/path" under default.rsync |
| rsync + SSH for renames on remote | default.rsyncssh with host= and targetdir= |
| Enable compression in rsync | rsync = { archive = true, compress = true } |
| Custom rsync binary or wrapper script | rsync = { binary = "/path/to/wrapper.sh" } |
Service management
| When to use | Command |
|---|---|
| Validate config and start | sudo systemctl restart lsyncd |
| Check service status | sudo systemctl status lsyncd |
| Enable at boot | sudo systemctl enable lsyncd |
| Tail sync log | sudo less /var/log/lsyncd/lsyncd.log |
Install on RHEL-family systems: sudo dnf install lsyncd (requires EPEL on many releases).
Package installs and updates in this section use dnf command.
lsyncd — command syntax
One-liner synopsis from lsyncd(1):
lsyncd [OPTIONS] -rsync SOURCEDIR TARGET ...
lsyncd [OPTIONS] -rsyncssh SOURCEDIR TARGETHOST TARGETDIR ...
lsyncd [OPTIONS] CONFIGFILEConfig file default: /etc/lsyncd.conf (Lua syntax). lsyncd uses inotify to watch source, collates events for delay seconds, then spawns rsync (or local cp/rm/mv with default.direct).
lsyncd — command examples
Essential Check version and run a local one-liner
Confirm lsyncd is installed, then mirror /source/ to /target/ in the foreground so log lines print to the terminal.
Run the commands:
lsyncd --version
sudo mkdir -p /source /target
sudo lsyncd -nodaemon -rsync /source/ /target/In another terminal, create a file:
sudo touch /source/demo.txtSample output:
Version: 2.2.2
20:36:36 Normal: --- Startup ---
20:36:36 Normal: recursive startup rsync: /source/ -> /target/
20:36:36 Normal: Startup of /source/ -> /target/ finished.
20:37:21 Normal: Calling rsync with filter-list of new/modified files/dirs
/demo.txt
/
20:37:21 Normal: Finished a list after exitcode: 0Press Ctrl+C to stop foreground mode. Without -nodaemon, lsyncd backgrounds itself and logs to syslog or logfile.
Essential Minimal /etc/lsyncd.conf for local rsync
Production setups use a config file with logging and a sync block — this pattern matches most RHEL/CentOS guides.
Create /etc/lsyncd.conf:
Enable or disable the unit at boot with systemctl enable; the systemctl command documents enable --now, symlinks under /etc/systemd/system, and masks.
sudo tee /etc/lsyncd.conf <<'EOF'
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd-status.log",
statusInterval = 20,
nodaemon = false,
}
sync {
default.rsync,
source = "/source",
target = "/target",
delay = 10,
}
EOF
sudo mkdir -p /var/log/lsyncd
sudo systemctl enable --now lsyncdVerify sync after writing a file:
sudo touch /source/file1
sleep 12
ls /target/
sudo tail -5 /var/log/lsyncd/lsyncd.logSample output:
file1
Sun Jan 19 16:24:35 2020 Normal: Calling rsync with filter-list of new/modified files/dirs
/file1
/
Sun Jan 19 16:24:35 2020 Normal: Finished a list after exitcode: 0The delay value batches rapid saves before rsync runs.
Common Sync to a remote host with default.rsync
Push changes to a remote directory over rsync — SSH keys or ssh-agent must work non-interactively for the lsyncd user.
Config excerpt:
sync {
default.rsync,
source = "/source",
target = "backup-host:/target",
delay = 10,
}Restart and check logs:
sudo systemctl restart lsyncd
sudo tail -10 /var/log/lsyncd/lsyncd.logSample output:
Normal: --- Startup ---
Normal: recursive startup rsync: /source/ -> backup-host:/target/
Normal: Startup of /source/ -> backup-host:/target/ finished.Ensure backup-host resolves (DNS or /etc/hosts) and that passwordless SSH/rsync works as root or the service user.
Common Use rsyncssh for efficient remote renames
default.rsyncssh runs rsync for bulk sync but uses SSH mv/rm locally on the remote side for renames — faster than re-transferring large files.
Config excerpt:
sync {
default.rsyncssh,
source = "/source",
host = "backup-host",
targetdir = "/target",
delay = 10,
}Note: host and targetdir are separate — unlike default.rsync, which uses a single target = "host:/path" string.
Sample log line after startup:
Normal: recursive startup rsync: /source/ -> backup-host:/target/
Normal: Startup of "/source/" finished: 0Common Exclude patterns and control deletes
Skip transient files and optionally keep extra files on the target when sources are deleted.
Config excerpt:
sync {
default.direct,
source = "/source",
target = "/target1",
delay = 10,
exclude = { 'file*', '*tmp' },
delete = false,
}Restart and inspect startup log:
sudo systemctl restart lsyncd
sudo grep -A2 'excluding' /var/log/lsyncd/lsyncd.logSample output:
Normal: recursive startup rsync: /source/ -> /target1/ excluding
file*
*tmp| delete value | Behaviour |
|---|---|
| true (default) | Remove target files not in source |
| false | Never delete on target |
| 'startup' | Delete extras only at daemon start |
| 'running' | Delete during runtime, not at startup |
Advanced Mirror one source to several targets
Replicate the same tree to local and remote destinations with separate sync blocks.
Config excerpt:
sync {
default.rsync,
source = "/source",
target = "/target1",
delay = 10,
}
sync {
default.rsync,
source = "/source",
target = "backup-host:/target",
delay = 10,
}
sync {
default.rsync,
source = "/source",
target = "/target2",
delay = 10,
}After restart, logs show each startup rsync:
Normal: Startup of /source/ -> /target1/ finished.
Normal: Startup of /source/ -> /target2/ finished.
Normal: Startup of /source/ -> backup-host:/target/ finished.Alternatively, use a Lua for loop over a targets table when many destinations share identical options.
Advanced Enable archive and compression
Tune rsync flags inside the sync block for WAN links or large static trees.
Config excerpt:
sync {
default.rsync,
source = "/source",
target = "/target",
delay = 10,
rsync = {
archive = true,
compress = true,
},
}This maps to rsync -a and -z behaviour during each triggered sync. Check resulting rsync command lines in the log when debugging.
Advanced Run a script after successful rsync
Wrap rsync with a custom script to alert monitoring when a sync completes — the wrapper must exec rsync and preserve exit codes.
Example wrapper /usr/local/bin/rsync-notify.sh:
#!/bin/bash
/usr/bin/rsync "$@"
result=$?
if [ $result -eq 0 ]; then
echo "$(date): Completed sync" >> /var/log/lsyncd-sync.ok
fi
exit $resultReference it in config:
rsync = {
binary = "/usr/local/bin/rsync-notify.sh",
}Sample line in /var/log/lsyncd-sync.ok:
Wed Jul 1 14:05:01 IST 2026: Completed syncAdvanced Troubleshoot a failing lsyncd service
When sync stops, check systemd, config syntax, and whether rsync/SSH works manually.
Run the commands:
sudo systemctl status lsyncd
sudo lsyncd -nodaemon /etc/lsyncd.conf
sudo rsync -av /source/ /target/
sudo journalctl -u lsyncd --no-pager -n 30Sample healthy status excerpt:
● lsyncd.service - Live Syncing (Mirror) Daemon
Active: active (running)Common fixes: absolute paths in source/target, SELinux context on /source, SSH StrictHostKeyChecking for rsyncssh, and typos in Lua commas/braces.
lsyncd — when to use / when not
| Use lsyncd when | Use something else when |
|---|---|
|
|
lsyncd vs rsync alone
| lsyncd | rsync (cron/manual) | |
|---|---|---|
| Trigger | inotify events + delay batch | Schedule or manual |
| Latency | Seconds (configurable delay) |
Minutes to hours |
| Daemon | Yes | No |
| Remote moves | rsyncssh optimizes renames | Full re-copy unless --delete |
| Complexity | Lua config + service | Single command in crontab |
lsyncd calls rsync under the hood for most sync modes — test rsync/SSH alone before debugging lsyncd.
Related commands
File sync and remote access nearby.
| Command | One line |
|---|---|
| lsyncd | Live directory mirror daemon (this page) |
| ssh | Remote shell rsyncssh relies on |
Browse the full index in our Linux commands reference.
lsyncd — interview corner
What is lsyncd and how does it work?
lsyncd (Live Syncing Daemon) watches directories with inotify, waits a short delay to batch events, then spawns rsync (or local cp/rm/mv with default.direct) to mirror changes to another path or host.
It targets slowly changing trees — config directories, web roots, incremental DR mirrors — not live database files.
A strong answer is:
"lsyncd uses inotify to watch a source tree, batches changes for a few seconds, then runs rsync to push updates to a local or remote target. It's a lightweight live mirror, not a cluster filesystem."
When do you use default.rsync vs default.rsyncssh?
| Mode | Target syntax | Best for |
|---|---|---|
default.rsync |
target = "host:/path" |
Simple remote push; rsync over SSH |
default.rsyncssh |
host= + targetdir= |
Remote renames/moves via SSH without full re-upload |
Use rsyncssh when files are renamed often on the source and the remote is SSH-accessible — lsyncd issues remote mv/rm for efficiency.
A strong answer is:
"default.rsync uses a single host:/path target. default.rsyncssh splits host and targetdir and uses SSH for remote file ops — better when renames would otherwise force full re-transfers."
What does delete = false mean in lsyncd?
By default lsyncd deletes files on the target that were removed from the source — true mirror behaviour. delete = false keeps extra files on the target even when they disappear from the source.
Other values:
'startup'— prune extras only when the daemon starts'running'— prune during runtime but not at startup
Pick false when the target is a backup you never want automatically trimmed.
A strong answer is:
"delete true mirrors removals to the target. false keeps orphan files on the target — I use that for one-way backups where the destination accumulates history."
Why does lsyncd use a delay setting?
delay (seconds) collapses many rapid inotify events (save, temp file, rename) into one rsync call. Without it, editing a large tree could spawn rsync storms.
Trade-off: higher delay = fewer rsync runs but more latency before the target catches up.
A strong answer is:
"delay batches inotify events before rsync runs — reduces load when editors write many files quickly. I tune it between a few seconds for low latency and longer for busy trees."
How do you install lsyncd on RHEL?
lsyncd is commonly packaged in EPEL, not always in base RHEL repos:
sudo dnf install epel-release
sudo dnf install lsyncd
sudo systemctl enable --now lsyncdConfig lives in /etc/lsyncd.conf (Lua). Validate with lsyncd -nodaemon /etc/lsyncd.conf before enabling production sync.
A strong answer is:
"On RHEL I enable EPEL and install the lsyncd RPM, configure /etc/lsyncd.conf, test with -nodaemon, then enable the systemd unit."
Troubleshooting
| Symptom | Likely cause | What to try |
|---|---|---|
| Service fails at start | Lua syntax error in config | lsyncd -nodaemon /etc/lsyncd.conf |
| Files never appear on target | Relative paths, wrong trailing slash | Use absolute paths; match /source/ vs /source |
| Remote sync silent failure | SSH host key or auth | Manual rsync -av /source/ host:/target/ as service user |
| inotify limit exceeded | Many watches | Raise fs.inotify.max_user_watches sysctl |
| Target deletes unexpected files | delete = true default |
Set delete = false if backup must retain old files |
| High CPU | delay too low on busy tree | Increase delay; use default.direct locally |

