When a web application moves to multiple servers, each node must find the correct code, uploads and application state. Without a plan, an image can exist on one node but return a missing-file error on another, or two writers can overwrite each other’s work. NFS provides a shared network filesystem, SSHFS exposes remote files through SFTP over SSH, and rsync copies files into separate targets. This guide compares their permissions, consistency and failure behavior, then applies them to WordPress, Laravel, code releases and backups. These approaches can be considered for deployments using VPS, dedicated or colocation servers; the selected service must support the required access and administration.
What Problem Are We Really Solving?
Before choosing NFS, SSHFS or rsync, it helps to be very clear about what kind of data you are trying to share between web servers. In practice, you almost always deal with one or more of these categories:
- Application code (PHP, Node.js, Laravel, WordPress core, theme and plugin files).
- User uploads (images, PDFs, videos, avatars, reports, export files).
- Generated assets (build artifacts, compiled JS/CSS, resized thumbnails).
- Sessions and cache data (PHP sessions, object cache, queues, temporary files).
- Logs (access logs, error logs, application logs).
Not all of these should be handled with the same mechanism. For example, file-based sessions shared over NFS can work, while Redis or Memcached can avoid shared-filesystem I/O. Performance and reliability depend on the session handler, eviction policy and failure-recovery design. We have a separate deep dive on this in our article choosing PHP session and cache storage: files vs Redis vs Memcached.
User uploads can live on a central file server or in object storage, as discussed in our guide to offloading WordPress and WooCommerce media to S3/MinIO-compatible storage. Separate public media from private reports and exports: a shared directory does not mean every file should be publicly accessible. Identify which data changes frequently, which files are complete and immutable, who may write them, and how soon other nodes must read them.
Quick Overview: NFS, SSHFS and rsync
NFS (Network File System)
NFS exposes a directory on one server as a network filesystem that other servers can mount as if it were a local disk. The NFS client handles remote read/write operations. Web nodes can mount the export at the same path (for example /var/www/shared) and use familiar filesystem operations, but caching and locking behavior can differ from a local filesystem.
This makes NFS a candidate for sharing user uploads, configuration or home directories across web servers. Concurrent writes to the same file still require application-level coordination.
SSHFS
SSHFS is a FUSE-based filesystem that tunnels file operations over SSH. You need SSHFS and FUSE support on the client and an SSH server with SFTP access on the “storage” machine. Authentication can use SSH keys, without a separate NFS service or port.
It feels like “NFS over SSH”, but internally it is very different: it lives in userspace, can add overhead, and should not be assumed to provide the same filesystem semantics as NFS.
rsync
rsync is not a filesystem at all; it is a file synchronization tool. You run it periodically (or triggered) to push or pull changes between directories. rsync can transfer differences (deltas) rather than entire changed files, can preserve permissions, hardlinks and ownership with suitable options and privileges, and works over SSH.
This is useful for one-way replication: publishing new code releases to multiple web servers, syncing uploads from a primary node to secondaries, or copying files as part of a backup process. A synchronized copy alone does not provide backup history.
How NFS Works in a web hosting Setup
Designate a file server and define exactly which clients need access. In this illustrative Linux example, /srv/web-uploads is the root of a dedicated filesystem on 10.0.0.10; the two permitted clients are 10.0.0.11 and 10.0.0.12. Confirm that layout first: exporting an arbitrary subdirectory is not equivalent to filesystem-level isolation. An /etc/exports entry could be:
/srv/web-uploads 10.0.0.11(rw,sync,root_squash) 10.0.0.12(rw,sync,root_squash)
Configure and activate the export using the server’s NFS administration procedure, then verify the effective export list. Match the non-root application UID/GID and server-side directory permissions; root_squash maps remote UID/GID 0 to an anonymous identity, not all users. Restrict network access to the intended clients. Each client needs NFS tools and an existing empty mount point; mounting over a populated directory hides its local contents. With the export reachable, an administrator can mount it:
mount -t nfs 10.0.0.10:/srv/web-uploads /var/www/uploads
The application uses normal file APIs but must account for latency, I/O errors and caching. This mount command uses negotiated protocol/options rather than a universal tuning recipe; verify the effective settings, application-user access and behavior after reboot in your deployment. Default Linux hard retries can leave processes waiting during an outage. Choosing soft merely to avoid hangs can introduce data-corruption risks. The server-side sync export requests stable storage before replies; it is distinct from the client’s sync mount option. See the exports manual and Linux NFS manual.
Pros of NFS for Web Clusters
- Shared backing files: An upload does not need a separate replication job for each node. Linux close-to-open behavior flushes changes on close and checks freshness on a subsequent open; already-open handles, directory/negative-lookup caches and application caches still matter. Do not assume instant visibility everywhere.
- Familiar operations: Ownership, permissions, symlinks and locks are available. Align UID/GID values and test the application’s locking and concurrent-write behavior; NFS does not resolve conflicting writes for you.
- Linux support: Client support is widespread, but the chosen image may require installation of NFS utilities.
- Measurable LAN performance: Latency, small-file metadata work, caching and storage affect results. A fast port or NVMe device alone does not prove adequate capacity. See NVMe, SATA SSD and HDD storage choices for the storage side.
- Central backup scope: Shared files can be backed up at the file server. Coordinate writes or use an appropriate consistent snapshot, retain separate recovery points, and back up the database and other application state too.
Cons and Pitfalls of NFS
- Shared failure dependency: If the NFS service or storage fails, operations needing that share may block or fail. The impact depends on what the application keeps there. Consistent storage, NFS service failover and client lock recovery all need testing; redundant disks, servers or a movable IP alone are insufficient.
- Resource bottlenecks: The server and network must handle remote I/O not satisfied by caches. Uploads, generated files and metadata-heavy access can exhaust capacity even when large-file throughput looks healthy.
- Locking and caching: Applications must account for remote visibility and recovery. NFSv3 uses separate locking services; NFSv4 includes locking in the protocol. Do not disable locks as a generic performance tweak.
- Security configuration: Limit client addresses and file permissions. Default
sec=sysdoes not provide cryptographic user authentication or traffic privacy;root_squashdoes not correct that limitation. - Distance and packet loss: WAN latency and interruptions can make synchronous file operations expensive or leave requests waiting. Test the actual path rather than infer suitability from a network label.
When NFS Makes Sense
NFS is worth considering in these scenarios:
- WordPress/PHP clusters needing shared uploads, such as a few nodes within one data center. A count such as two to five nodes is illustrative, not an NFS capacity rule.
- Shared home directories where identities, permissions and user workloads can be managed consistently.
- Legacy applications requiring filesystem APIs that cannot easily use object storage, provided their locking, cache and failure expectations are tested.
You should be more cautious using NFS for:
- Bursty write workloads: Measure concurrent uploads and metadata activity instead of choosing by traffic category alone.
- Sessions: Compare file-based handling with an application-supported Redis, Memcached or database handler; expiry, eviction, locking and recovery matter as much as speed.
- Cross-region access: Measure latency and define behavior when the link or remote storage is unavailable.
- Database storage: Do not give independent active MySQL/PostgreSQL servers the same physical data directory. Whether one database instance can use NFS is a separate question from replication between independent instances. PostgreSQL permits NFS with a
hardmount and correct durability behavior, and strongly recommends a serversyncexport. Clientsyncis not required because PostgreSQL issues its ownfsynccalls. MySQL 8.4 recommends careful testing and NFSv4 or later; each independent instance needs its own data directory. Shared-disk failover must prevent simultaneous active access. Copying a running database directory with rsync is not, by itself, a consistent database backup.
Consult PostgreSQL’s storage requirements, its replication and shared-disk guidance, and MySQL 8.4’s NFS discussion for the database-specific constraints.
SSHFS: Convenient Access Through SSH
How SSHFS Works
SSHFS needs client-side SSHFS/FUSE support and server-side SFTP access. Run it as the intended mounting user, create a mount point that user owns, and check that the remote account can access the source. The following example uses a single SSH identity and is for that mounting user; it does not automatically grant a separate web-server user access:
sshfs user@10.0.0.20:/srv/uploads /var/www/uploads -o IdentityFile=/home/user/.ssh/id_rsa
Remote operations pass through SSHFS in user space and SFTP over SSH; caching can avoid some requests. By default only the mounting user can access the mount. allow_other expands local access and should be assessed with default_permissions, identity mapping and the system’s FUSE policy. The server still sees the remote SSH account, so local user separation does not create independent server-side identities.
Advantages of SSHFS
- Simple server-side setup: SSHFS can reuse an existing SSH service with SFTP access rather than require NFS exports. The client still needs SSHFS and FUSE support.
- Encrypted by default: All traffic is wrapped in SSH. You don’t need to add extra encryption layers.
- Account-based access with SSH keys: A dedicated SSH user can authenticate with its own key. Filesystem permissions or server-side restrictions, not the key alone, determine which files it can access.
- Great for ad‑hoc mounts: For one-off maintenance tasks, manual file inspection or quick migrations, SSHFS is very handy.
Limitations and Risks of SSHFS in Web Hosting
- Workload-dependent overhead: SSH encryption and FUSE add work, but the comparison with NFS depends on the files, concurrency, cache and network. Test the intended workload rather than assume a fixed speed ranking.
- Connection loss: Network operations can wait indefinitely by default. SSH keepalive settings help detect a broken connection; they do not protect in-flight writes. With
reconnect, accesses to files opened before reconnection can fail and those files must be reopened. - Filesystem differences: Hardlinks can appear as distinct inodes. Atomic rename depends on the SFTP server; the rename workaround that removes an existing destination first is not atomic. Test application requirements instead of assuming local-filesystem semantics.
- Production dependency: If requests, sessions or transactional data depend on the mount, define how the application recovers from blocked or failed I/O. A forced disconnect does not prove pending writes completed.
The upstream SSHFS manual documents permission, reconnection and filesystem limitations.
When SSHFS Is (and Is Not) a Good Idea
Where SSHFS can shine:
- Temporary admin access to a remote file tree from a management server or engineer’s workstation.
- Low-traffic internal tools where convenience is more important than peak performance.
- One-off migrations when you want to browse or copy files interactively before switching to rsync or another tool.
Workloads requiring additional validation before using SSHFS include:
- A primary shared filesystem serving production web requests.
- Session/cache files for a busy PHP or Laravel application.
- Databases or other transactional storage with durability and locking requirements that have not been demonstrated on this stack.
If SSHFS is already in the application’s critical path, measure its actual limitations before planning a migration. NFS, rsync distribution and object storage have different interfaces and consistency behavior; switching tools requires a tested data and application transition, not just a new mount.
How rsync Fits into Multi-Server Architectures
rsync synchronizes files between two directories. Examples in multi-web-server setups include:
- CI/CD to application nodes: Transfer a validated build to unpublished release directories.
- Single writer to readers: Copy completed uploads or exports to nodes that the application does not write to.
- Backup transfer: Copy data into a process that separately provides retained history, consistency, access isolation and restore tests.
For code distribution, first prepare a trusted, complete ./release/ tree containing no uploads, secrets or mutable application data. Create the dedicated, unpublished release destination on each host and confirm the account can write it. The following two commands only preview changes. The trailing slash copies the source directory’s contents; verify the exact paths and every proposed deletion:
rsync -a --dry-run --itemize-changes --delete -e ssh ./release/ web1:/var/www/releases/example-build/
rsync -a --dry-run --itemize-changes --delete -e ssh ./release/ web2:/var/www/releases/example-build/
After reviewing a preview against a frozen source, remove only --dry-run to transfer that release, checking each exit status and target contents. A preview is not a lock against changes between runs. Keep the target outside the live release and outside persistent data; --delete removes extra files in the synchronized target tree. These commands do not activate a release, coordinate nodes or guarantee downtime-free deployment. Compression is omitted because already-compressed media or a fast network may not benefit from -z.
Pros of rsync
- Conditional bandwidth savings: The default changed-file check uses size and modification time.
--checksumchanges that selection and adds reads; it is distinct from transfer integrity checks. Delta transfers can reduce network traffic, while local-to-local copies normally transfer whole files. - Flexible distribution: One source can feed several targets. For many-to-one log collection, use separate per-source paths and handle rotation; rsync is not a continuous log collector.
- Explicit SSH transport: SSH encrypts the transfer and authenticates the endpoint. A direct rsync daemon connection is not automatically SSH-encrypted.
- Metadata control:
-adoes not include ACLs, extended attributes or hardlinks. Add-A,-Xor-Honly where needed and supported, with the required permissions. - Backup generations:
--link-destcan share unchanged files between separately retained generations using hardlinks. Protect old generations from modification; hardlinks are not independent copies against every failure.
Cons and Design Gotchas with rsync
- Copy lag: Scheduling every five minutes does not guarantee five-minute freshness; transfer duration, failures and queued work can extend it.
- Conflicting writers: Two runs in opposite directions do not make conflict-aware bidirectional sync. Source changes, overwrites and deletions can destroy the other node’s version.
- Operational controls: Prevent overlapping jobs and monitor exit status, last successful completion, file age and target readability. Partial-transfer codes such as 23 or 24 require investigation rather than being treated as complete success.
- Mixed releases: File and directory updates are not an atomic cluster-wide change. Upload to a separate release directory and coordinate validation and activation.
rsync for Code Deployments and Blue-Green Releases
Use one immutable release directory per build. After transfer and validation, a deployment system can atomically replace a symlink on a single host using a supported same-filesystem rename. This changes one directory entry; it does not update every server simultaneously or switch already-running PHP/worker processes. Prepare cache and process handling, health checks, traffic draining and compatible database changes as part of the release.
Our rsync, symlink and systemd deployment guide covers the broader pattern. Returning the code pointer to an older release does not undo database writes, schema changes or external side effects. Retain compatible code and assets and define when rollback remains valid.
rsync for Upload Replication
For user uploads, a common pattern is:
- Designate one upload writer and route all upload forms/APIs to it. Define how writes stop or transfer to a new authoritative node when it fails.
- Publish only completed files on the source, then copy them to application-read-only targets. Monitor transfer results and confirm the intended targets can read them.
- Until a file is confirmed on a target, direct reads to the authoritative source or keep it unpublished there. “Briefly missing” is not a safe guarantee: a failed job or source outage can leave the file unavailable indefinitely.
This model can remove the need for a shared filesystem when the application can manage lag and a single writer. Object storage with CDN is another option if the application supports its API and access model. Regional availability, durability, authorization and cache behavior depend on the selected service; no choice removes those design questions.
Instead of asking “Which is better, NFS, SSHFS or rsync?”, the more useful question is: Which combination fits the data types and traffic patterns of my application?
Data-Type-Driven Choices
- Application code: Separate release directories on each node can reduce dependence on network storage at request time. Keep code and built assets aligned. OPcache mainly stores bytecode in shared memory and also supports optional disk caching; it is not a shared application-data folder. Whether a PHP request reads source files from NFS depends in part on cache state and configuration.
- User uploads: NFS offers shared file APIs with caching and failure constraints. Single-writer rsync offers separate copies with explicitly managed lag. Object storage requires application/plugin compatibility and access-policy design; compare object, block and file storage.
- Sessions and cache: Choose a supported handler and define locking, expiry, eviction and failover. Shared files, Redis, Memcached and database-backed sessions have different tradeoffs; see PHP session and cache storage choices. Installing a cache service does not automatically migrate every session mechanism.
- Logs: Local buffering plus a central collector can separate log delivery from request-time shared storage. If using rsync for completed log files, separate source paths and manage rotation. See centralizing logs with ELK and Loki.
Example Architecture: Small WordPress Cluster
Consider an illustrative three-node WordPress cluster behind a load balancer. The nodes could use VPS or dedicated servers, subject to the selected service’s network access and administration capabilities.
- Code: Deploy the same core, plugin, theme and asset release to each node, then coordinate the traffic transition.
- Uploads: Mount the shared upload area at the installation’s
wp-content/uploadspath (for example,/var/www/html/wp-content/uploads) and verify UID/GID, permissions and new-file visibility. Prevent uploaded files from being executed as application code. - Application state: Use the same production database and compatible application keys/cookie settings. WordPress object cache with Redis or Memcached is separate from the actual WooCommerce cart/session or plugin PHP-session implementation. Test login, cart and checkout when requests move between nodes.
- Backups: Back up files and database state with appropriate consistency, separately retained generations and restricted credentials. Using a copying tool or object-storage destination alone does not supply ransomware-resistant history.
Web-node replacement becomes more repeatable when mutable state is deliberately separated. A replacement still needs matching configuration, secrets, permissions, code, storage access and health checks before it rejoins traffic. Mounting NFS and copying code alone does not prove the node is ready.
Example Architecture: Static Asset Build + rsync Fan-Out
For a Laravel or SPA frontend project, you might build all assets in CI, then:
- Produce a versioned immutable asset build.
- Transfer it to a separate versioned path on every node, checking exit status and required files.
- Only then publish HTML that references that version. Retain older assets while cached HTML or ongoing sessions may still request them.
For these immutable assets, rsync can supply distribution without NFS, provided activation and retention are coordinated. Laravel API/queue workflows need a different check: both processes must use a disk configuration and permissions that reach the intended file. The public disk defaults to storage/app/public, exposed through public/storage; private reports should remain on a separate private disk. Finish the file write and required durability steps before queuing processing, use completed names rather than exposing partial files, and make retries safe. Laravel after_commit/afterCommit waits for database commits, not for file completion. See the filesystem and queue transaction documentation.
Operational Considerations: Performance, Security, Backups
Performance Tuning for NFS and rsync
Whichever method you pick, you must watch resource usage. We strongly recommend monitoring your servers with tools like htop, iotop, and a metrics stack. Our article on monitoring VPS resource usage with htop, iotop, Netdata and Prometheus walks through a practical setup.
For NFS performance:
- Measure storage latency, metadata operations, queue depth and cache behavior under representative concurrent load; faster storage alone does not eliminate network limits.
- Size bandwidth and latency from actual workload requirements rather than a universal 1 or 10 Gbps rule.
- Read/write sizes are normally negotiated. Inspect effective
rsize/wsizeand measure before overriding them. Genericnoatime/nodiratimeoptions have no effect on Linux NFS mounts, andintrhas been ignored since Linux 2.6.25. - Track blocked operations and retries with
hardmounts. Do not trade away correctness withsoft, disabled locking or serverasyncexports merely to improve a benchmark.
For rsync performance:
- Schedule large copies to avoid competing with request traffic and measure scan, CPU, disk and network costs.
- Preview
--deleteusing--dry-run --itemize-changes; validate source contents, trailing-slash semantics and target scope. Keep persistent uploads outside code-release targets. --partialretains incomplete transfers; a private--partial-dircan separate those files from published data. This helps resumption in suitable modes, not consistency or backup retention.--inplacewrites into the target during transfer; interruption can leave it inconsistent, and hardlinked backup generations can be changed together. It is not a general optimization for live files or database copies.
The official rsync manual documents selection checks, transfer modes, deletion and partial-file behavior.
Security Best Practices
- NFS access: Restrict exports and firewall rules to the necessary clients. Use non-root application identities, correct ownership and narrow permissions. Keep
root_squash; do not treat it as cryptographic authentication or complete client isolation. - NFS privacy: A private network does not encrypt
sec=systraffic. Where needed, evaluatekrb5por supported, enforced RPC-over-TLS on both ends. Merely enabling TLS support does not necessarily forbid plaintext clients. - SSHFS/rsync over SSH: Verify host keys and use restricted accounts with appropriate file permissions. Authentication keys do not confine an account to a directory.
- Restricted rsync accounts: The upstream rrsync wrapper can restrict directories and operations. Review alternate shell access and writable startup files as well; a casual
command=prefix is not proof of a complete sandbox. Validate SSH changes before relying on them for continued access.
Backups and Ransomware Resilience
Neither a shared NFS export nor a second rsync target supplies independent backup history. Overwrites, ransomware-encrypted files and deletions can propagate to accessible copies. Separate backup permissions and retained recovery points from live distribution, and verify that a restore works without the failed production system.
A robust strategy often follows the 3‑2‑1 rule (3 copies of data, 2 different media, 1 off-site). Our article on designing a backup strategy with realistic RPO/RTO and our guide to ransomware‑resistant hosting backups provide concrete checklists you can apply on top of your file-sharing design.
How to Choose: NFS vs SSHFS vs rsync
To wrap the comparison, here is a high-level decision table for multi-web-server setups:
| Scenario | Option to evaluate | Required checks |
|---|---|---|
| Shared uploads through filesystem APIs | NFS | Permissions, concurrent writes, cache visibility, durable storage and failover |
| Code distribution to several nodes | rsync | Unpublished release directories, validation, coordinated activation and rollback compatibility |
| Temporary remote file access | SSHFS | SFTP/FUSE prerequisites, mounting user, remote permissions and connection recovery |
| Single-writer upload copies | rsync | Managed lag, read routing, source failover and separate backup history |
| Sessions and cache | Application-supported handler | Actual session mechanism, expiry, locking, eviction and recovery |
A starting design to test against your workload is:
- Local release directories with coordinated code distribution.
- NFS or application-compatible object storage for shared uploads, according to access and failure requirements.
- An explicitly configured session handler and separate cache policy.
- Independent backup generations with access controls and restore tests, using rsync only where it fits the transfer process.
Choose by File Access and Failure Requirements
NFS, SSHFS and rsync solve different parts of multi-server file management. NFS exposes shared files with network, cache and lock behavior to account for. SSHFS is convenient for temporary access, with SFTP permissions and reconnect limitations. rsync distributes separate copies and can support release and backup workflows, but requires explicit handling of lag, deletion and publication. None of these tools automatically resolves concurrent writes or provides a complete backup strategy.
Document the writers, readers, freshness target and acceptable outage behavior for each data type. Then compare DCHost service options with the required mount privileges, network access, capacity and administration responsibilities; verify package-specific capabilities rather than assume them. Before production use, test permissions, concurrent access, interrupted transfers, recovery and a restore from independently retained backups.





