Most applications keep their state in a database, and the best home for a database is [local storage](/docs/hetzner/apalla/storage/local/local-nvme-with-topolvm) on a bare metal server. A shared filesystem answers a narrower need: several pods on different nodes reading and writing the same files at once. Before you compare shared-filesystem backends, make sure that is really the problem you have. Even then, a filesystem is usually not the first answer. Most cloud-native applications share data through [object storage](/docs/hetzner/apalla/storage/object/use-s3-from-workloads) over the S3 API, and that is the recommendation here too. Object storage is the building block. Run your own S3 store with [SeaweedFS](/docs/hetzner/apalla/storage/object/run-seaweedfs) on local or block volumes, or point at an external S3-compatible store, which is often the easier path. Either way the data is decoupled from the pods that use it, and scales without a filesystem server in the way. A ReadWriteMany filesystem is the fallback. It fits an application that needs a real filesystem and cannot use the S3 API, when rewriting or migrating it to object storage is not an option yet. That is common with in-house and legacy apps. In that case JuiceFS and NFS both give you RWX, and they differ in where the data lives. ```mermaid flowchart TD A["Data shared across pods on different nodes?"] -->|No| B["ReadWriteOnce on a block or local volume"] A -->|Yes| S{"Can the app use the S3 API?"} S -->|"Yes, or can be adapted to"| O["Object storage: self-hosted or external"] S -->|"No, needs a filesystem and cannot migrate yet"| R["ReadWriteMany filesystem: JuiceFS or NFS"] ``` ## The options side by side When a shared filesystem is genuinely the answer, JuiceFS and NFS are the two backends, with single-node ReadWriteOnce as the no-sharing baseline: | Backend | Availability | Latency | Cost | Operational effort | | ------------------------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------ | | [JuiceFS](/docs/hetzner/apalla/storage/shared/readwritemany-with-juicefs) | As high as its metadata engine, given a durable object store | Higher; every operation talks to the metadata engine and object store | Object-store pricing, often per request | Most: an object store, a metadata engine, and the CSI driver to run well | | [NFS](/docs/hetzner/apalla/storage/shared/nfs-option) | Limited by the single server | Higher than local disk; every operation crosses the network to the server | One block or local volume plus the server pod | Less to run, but a single point of failure | | Single-node RWO | Tied to one node and its volume | Local disk speed | One block volume | Least, but no sharing across nodes | ## Availability comes from the metadata engine JuiceFS keeps its file data in object storage and its directory tree in a metadata engine, usually Redis or PostgreSQL. That engine sits on the write path for every file operation. If it stops, the filesystem stalls, even though the object store is fine. So the availability of a JuiceFS filesystem is the availability of its metadata engine. Run that engine with real redundancy if the shared data matters. NFS has a simpler and weaker story. One server holds the export. If it goes down, every mount blocks until it returns. There is no metadata engine to protect, but there is also no built-in path around the loss of the one server. ## Latency and small files Neither backend is as fast as a local disk, because both cross the network. The pattern that hurts most is many small files. On JuiceFS, each file operation may involve a round trip to the metadata engine and a request to the object store. On NFS, each one crosses the network to the server. A workload that reads and writes thousands of tiny files feels this far more than one that streams a few large files. ## Cost on object storage JuiceFS inherits the cost model of whatever object store backs it. Object storage often charges per request, so the small-file pattern costs money as well as latency. The CSI driver applies a quota from the PVC's requested size by default, so that size is a real ceiling rather than a label. If you run your own object store with [SeaweedFS](/docs/hetzner/apalla/storage/object/run-seaweedfs), you avoid per-request charges but you take on operating the store. NFS cost is the cost of one block or local volume plus the server pod that fronts it. Simpler to reason about, but it does not spread across nodes. ## The operational question The honest tradeoff is effort against resilience. NFS is faster to stand up and easier to understand, with a single point of failure to accept. JuiceFS survives node loss and scales past one disk, and asks you to run an object store and a metadata engine well. Pick NFS when the shared data is modest and simplicity wins. Pick JuiceFS when the shared data must outlive any one node and grow without bound. If you choose JuiceFS and need a self-hosted object store to back it, start with [Run SeaweedFS](/docs/hetzner/apalla/storage/object/run-seaweedfs). Want a second opinion on the choice, or the backend you pick set up and operated for you? The Syself Consulting team is glad to help with either.