37.1 NFS Overview: Network File System Versions (v3 vs v4)
Alright, let’s talk about NFS versions. This isn’t just a matter of bigger numbers being better; it’s a fundamental shift in philosophy. The jump from v3 to v4 is like trading in a trusty, greasy socket set for a brand new, all-in-one, computerized tool kit. The old one is simple and you know exactly how it breaks, but the new one can do things the old one could only dream of, provided you read the manual and don’t mind the occasional proprietary bolt.
The Old Guard: NFSv3
NFS version 3 is the workhorse you’ll find in a million data centers. It’s stateless, which is its greatest strength and its most profound weakness. What does ‘stateless’ mean? It means the NFS server doesn’t keep track of who has what file open. Each client operation—read, write, etc.—is a completely independent transaction. The server doesn’t care what happened before and doesn’t expect anything afterward.
This is brilliant for resilience. If your NFS server reboots, clients can just carry on once it’s back. There’s no session state to rebuild. But this simplicity comes at a cost. For example, file locking—a crucial feature for anything that might, you know, write to a file—had to be bolted on as a separate protocol (the Network Lock Manager, or NLM). This made the whole thing a bit of a Rube Goldberg machine.
Here’s a classic /etc/exports line for an NFSv3 share. You’ll notice we’re just throwing a network range at it.
# /etc/exports on the server
/data 192.168.1.0/24(rw,sync,no_subtree_check)
And mounting it on the client is equally straightforward:
# On the client
sudo mount -t nfs -o vers=3 nfs-server.example.com:/data /mnt/data
The sync option is non-negotiable for data integrity—it makes the server only reply to a write request once the data is safely on disk. Without it, you’re living on the edge, hoping your server never crashes between receiving data and actually writing it. Don’t hope. Use sync.
The New Regime: NFSv4
NFS version 4 is a complete redesign. It’s stateful, meaning the server and client maintain a session. This single change unlocks a world of improvements. File locking is now built directly into the protocol, so it’s actually reliable. It uses a single well-known port (2049), which is a godsend for firewall configurations—no more wrestling with rpcbind and a dozen random ports.
But the biggest game-changer is compound operations. Instead of the client sending a “lookup this file” request, waiting for a reply, then sending a “read it” request, it can bundle those into a single packet. This drastically reduces latency, especially over high-latency links like the internet. Yes, you can actually use NFSv4 over the internet, especially with Kerberos security, which is another thing v4 gets right that v3 largely ignored.
Here’s the equivalent v4 setup. Note the different syntax and options.
# /etc/exports on the server for v4
/data /24(rw,sync,fsid=0)
Mounting on the client now looks like this. The vers=4.2 specifies the highest version we’ll try to use.
# On the client
sudo mount -t nfs -o vers=4.2 nfs-server.example.com:/data /mnt/data
See the difference? The server path is just /. That’s because NFSv4 has a proper filesystem model. The fsid=0 option in the export marks this as the root of the server’s NFSv4 pseudo-filesystem. You can export multiple directories and have them appear as subdirectories under this root, which is far more elegant than v3’s “everything is its own isolated mount” approach.
So, Which One Should You Use?
Unless you’re shackled to some ancient equipment that only speaks v3, you should be using NFSv4. The performance, security, and manageability benefits are overwhelming. The one legitimate gripe against v4 is that its stateful nature means a server reboot will indeed break client applications until they reconnect. But in the modern era of highly available storage clusters, this is a manageable problem.
The most common pitfall I see is clients and servers silently negotiating down to an older version because of a misconfiguration. Always explicitly specify the version you want (vers=4.2) on the client mount. Don’t let it guess. Be direct. It respects you more for it. And for the love of all that is holy, never, ever use async on your exports unless you enjoy the unique sensation of data loss.