Telnyx Storage: CloudFS (Beta) — Full Documentation
Complete page content for CloudFS (Beta) (Storage section) of the Telnyx developer docs (https://developers.telnyx.com). This file: https://developers.telnyx.com/development/llms/storage-cloudfs-beta-llms-full-txt.md · Root index: https://developers.telnyx.com/llms.txt
Get Started
CloudFS
Source: https://developers.telnyx.com/docs/edge-compute/cloudfs.mdCloudFS is a POSIX filesystem you mount on any host or container. Once mounted, it behaves like a local directory —
read, write, mkdir, rename, git init — but every byte is stored durably in Telnyx Cloud Storage, and the same filesystem can be mounted by many clients at once — a fleet of agents reading and writing it concurrently.
You mount it with the open-source JuiceFS Community Edition client (Apache-2.0), which you run yourself — Telnyx does not host or bundle it. JuiceFS has no server process: the client does all the filesystem work and talks directly to a metadata database and to object storage, so no JuiceFS component runs on the Telnyx side. Telnyx provides and authenticates the two managed backends — the metadata database and object storage — and hands you a ready-to-mount filesystem.
The target use case is a shared, persistent filesystem for AI agents: provision one CloudFS, mount it once, and every file, repo, and checkpoint an agent produces is there — and still there on the next mount, from anywhere.
Do not touch the cloudfs-fs-* bucket directly. A CloudFS filesystem’s data lives in a bucket named cloudfs-fs-<hex> inside your own Telnyx Cloud Storage account — it appears alongside your other buckets and is reachable with your API key. Its objects are opaque JuiceFS blocks (chunks/… plus internal bookkeeping), not your files. Deleting, renaming, or editing objects in that bucket out of band corrupts the filesystem — a missing block is unrecoverable and there is no repair path. Manage a CloudFS filesystem only through the CloudFS API and a JuiceFS mount; treat its bucket as internal, hands-off storage.
CloudFS is in beta. The API surface and behavior may still change as it moves toward general availability.
Next Steps
- Quick Start — Create a filesystem and mount it end-to-end
- How CloudFS Works — The two-lane architecture and credentials
- Mounting — The verified
juicefs mountrecipe - Serving Without FUSE — A WebDAV endpoint for hosts that can’t mount
- Concurrent Access — Mount the same filesystem from many clients at once
- API Reference — The
/v2/storage/cloudfsendpoints
Related Resources
- Cloud Storage authentication — How the API key is used as the S3 access key
- Object Storage — The S3-compatible storage CloudFS is backed by
Quick Start
Source: https://developers.telnyx.com/docs/edge-compute/cloudfs/quickstart.mdGet up and running with CloudFS: create a filesystem over the API, then mount it with the JuiceFS client inside a Linux container and use it like any local directory — write files, read them back, run
git. The whole path below is verified end-to-end against production.
CloudFS is built on JuiceFS Community Edition (see How CloudFS Works for the architecture). There is no server process to run: the JuiceFS client on your host talks directly to a per-filesystem metadata database and to Telnyx Cloud Storage. That means you hold two credentials — the meta_token (returned on create) and your TELNYX_API_KEY — and the client does the rest.
1. Create a Filesystem
POST /v2/storage/cloudfs. The Idempotency-Key header is required (a request without it is rejected with 400), and so is region — there is no default. Allowed regions are us-central-1, us-east-1, and us-west-1.
Idempotency-Key returns the same filesystem instead of creating a second one. A 201 response looks like this:
meta_url (with the token inline as the password) and the standalone meta_token are returned only on create and on rotate. GET /v2/storage/cloudfs/{id} returns meta_url without the token and no meta_token at all — it cannot be read back. Store the token securely now; if you lose it, rotate to get a new one.
You’ll use two values from this response to mount:
meta_url— the full connection string, token included. This is the metadata endpoint; the host is alwaysus-east-1.telnyxcloudfs.comregardless of the filesystem’s region.id— the filesystem UUID, for later API calls (detail, rename, rotate).
s3_bucket (cloudfs-fs-<hex>) is in your Telnyx Cloud Storage account, but it holds CloudFS’s internal blocks — not your files. Never modify or delete its objects directly; that corrupts the filesystem. Read and write only through the mount below. See How CloudFS Works.
2. Mount It with JuiceFS
CloudFS pre-formats the volume during provisioning — the bucket already contains the JuiceFS volume metadata. Do not runjuicefs format. The filesystem is already formatted; running format against it fails with cannot update volume name. Go straight to juicefs mount. (The one exception: if the filesystem’s status is needs_format, it does need a one-time juicefs format before mounting — see Mounting.)
Mount inside a Linux container with FUSE — a portable path that runs the same anywhere and needs no FUSE install on the host. (You can also mount natively on any Linux or macOS host that has FUSE/macFUSE installed.) The data lane authenticates to Telnyx Cloud Storage over S3: your TELNYX_API_KEY is the access key, and the secret key can be any non-empty placeholder (Telnyx Storage ignores the SigV4 signature, but JuiceFS’s AWS SDK rejects an empty secret). See Cloud Storage authentication for why the secret is ignored.
/tmp/juicefs.log for progress. Once mounted, df -h /mnt/agentfs shows the volume.
3. Smoke-Test Over POSIX
The mount is a normal directory. Write a file, read it back, and initialize a git repo — all standard POSIX, no CloudFS-specific calls.chunks/… in the filesystem’s bucket, and persists across unmount and remount — remount with the same meta_url and your files are still there.
Next Steps
- How CloudFS Works — the metadata and data lanes, the two credentials, and the on-disk layout
- Mounting — the mount recipe in depth, FUSE requirements, and remount
- API Reference — the full endpoint surface, including rotate and delete
- Overview — what CloudFS is and when to use it
Concepts
Filesystems From First Principles
Source: https://developers.telnyx.com/docs/edge-compute/cloudfs/concepts/filesystems-from-first-principles.mdCloudFS gives you a POSIX filesystem you mount on any host or container, backed by Telnyx Cloud Storage. To understand how it works — and why it is shaped the way it is — these Concepts pages build the idea from the bottom up:
- What a filesystem is and how a local one is built (this page)
- Why past network filesystems fall short, and how the early cluster filesystems reframed storage (NFS and AFS → GFS, HDFS, MooseFS)
- How CloudFS puts it together
What a Filesystem Actually Is
Strip away the tooling and a filesystem is two abstractions:- A file is a linear array of bytes with a low-level name — a number, the inode number. The operating system does not care whether those bytes are a JPEG or C source; it stores them and hands them back intact.
- A directory is itself a file, but its contents are specific: a list of
(human-readable name → inode number)pairs. Nest directories inside directories and you get the tree you navigate every day.
/home/agent/work.log, a filesystem is really two things: an index that maps names to inodes and inodes to the location of bytes, and the bytes themselves. Everything else — open/read/write/close, permissions, hard and symbolic links — is built on top of those two.
How a Local Filesystem Is Built
On a single disk, those two things live in two different places. OSTEP’s teaching filesystem, vsfs, divides the disk into an inode table plus small bitmaps that track which inodes and blocks are free — this is the metadata index — and a much larger data region of fixed-size blocks that holds file contents. Each inode is a compact record of metadata (permissions, timestamps, size) plus a multi-level index of pointers to the file’s data blocks. Reading a file means reading its inode to find the block pointers, then reading the blocks; writing a file may also flip an allocation bit and rewrite the inode. The Fast File System added the lesson that where you place those blocks matters: the original Unix filesystem treated the disk like RAM and paid for it in seeks, so FFS made the filesystem “disk-aware” — keep an inode near its data, keep files of one directory together, respect the physical medium. The durable takeaway is this: a filesystem is a metadata index over a pile of data blocks — two kinds of state with two very different access patterns. Metadata is small, hot, and demands consistency: an inode is either allocated or it is not. Data is large and wants throughput. Hold onto that split; it is the key to everything that follows.Staying Consistent Across Crashes
The metadata index has one more demand: it must survive a crash. A single logical operation — appending a block to a file, say — touches several structures (the allocation bitmap, the inode, the data block), but the disk writes them one at a time. Lose power in between and the index is left inconsistent: a block marked used by no file, or an inode pointing at garbage. Early filesystems repaired this after the fact with fsck, scanning the whole disk on reboot — which stops scaling as disks grow. The durable fix, journaling (write-ahead logging), is borrowed straight from databases: write your intended changes to a log and commit them there first, then apply them to their real homes; after a crash, replay the committed log. Recovery then costs the size of the log, not the size of the disk. Keep this one in mind — it is the cleanest argument for where CloudFS keeps its metadata. And the medium underneath can lie: a sector rots, or silently returns the wrong bytes. Filesystems and storage layers defend against it with checksums and scrubbing; CloudFS leaves that to the object store, which does it for you.Further Reading
- Operating Systems: Three Easy Pieces — Files and Directories, File System Implementation, Locality and the Fast File System, Crash Consistency: FSCK and Journaling, and Data Integrity and Protection.
Network Filesystems
Source: https://developers.telnyx.com/docs/edge-compute/cloudfs/concepts/network-filesystems.mdA local filesystem is a metadata index over a pile of data blocks. To share one between machines you must move one or both of those halves across a network — and decades of distributed filesystems show that is where the difficulty lives.
NFS: Stateless, and Brittle Over the WAN
Sun’s Network File System makes the filesystem a client/server protocol. Its central design goal is simple, fast crash recovery, achieved by making the server stateless — it keeps no per-client state, so every request carries everything needed to service it (aREAD sends the explicit offset; the client, not the server, tracks position). Most operations are idempotent, so the failure handler collapses to a single rule: set a timer, and if no reply arrives, retry. Elegant — but it has costs that bite hard over a wide-area network:
- Weak cache consistency. Clients cache and buffer writes for performance, which introduces the update-visibility problem. NFS papers over it with flush-on-close and an attribute cache with a timeout (~3 seconds), so whether a client sees the latest version of a file “depends on whether the cache entry has timed out” — the source of NFS’s notorious occasional stale reads.
- The hang. Because the client simply retries until the server answers, an unresponsive or partitioned server makes the client block indefinitely. A
read()that never returns takes the calling process — and often a whole pipeline — down with it. A network partition is indistinguishable from a crash. - Small files are easy; large files are not. Over a LAN with small files NFS is fine. Over a WAN, file seeks and mid-file updates on large files get ugly, and rapid writes suffer under lost packets.
fileserver crashes or the network partitions, any process that so much as stats a path under /mnt/shared blocks in uninterruptible sleep — ls /mnt/shared hangs, shrugs off Ctrl-C, and the console fills with NFS server fileserver not responding, still trying. The mount doesn’t return an error; it waits, and takes the caller down with it. That is tolerable on a quiet LAN with a reliable server; for agents scattered across the internet — where partitions are routine and every mount is one flaky link from a hung process — it is the wrong default.
AFS: Whole-File Caching, and Stateful Bookkeeping
The Andrew File System was built for scale. Onopen() it fetches the whole file to the client’s local disk and serves subsequent reads and writes locally; on close() it ships the whole file back. To avoid clients constantly polling “has this changed?”, AFS added callbacks — a promise from the server to notify a client when a cached file changes — giving close-to-open consistency. It scales better than NFS, but the design fights our use case:
- Callback state is awkward for clients that come and go. A client that was offline may have missed an invalidation and must revalidate its whole cache on return; a rebooted server does not know which clients cache what and must have everyone re-validate. Ephemeral agents — containers that appear, work, and vanish — are exactly the clients this bookkeeping handles worst.
- Whole-file caching punishes the workload we care about. Fetching and rewriting an entire file just to append one line to a shared worklog, or to touch a small region of a large file, is precisely what AFS does poorly. AFS itself notes that its baseline consistency is not enough for concurrent updates to something like a shared code repository — you still need explicit file-level locking.
Separating Metadata From Data
By the early 2000s a different design had emerged — built for a fleet of cheap, failure-prone machines from the start, rather than making a single server’s disk look remote.Google File System
Google File System (GFS, 2003) split the problem cleanly in two:- a single master holds all the metadata — the namespace and the map from each file to its chunks — in memory, and
- a fleet of chunkservers holds the file data as large chunks (64 MB), replicated for durability.
HDFS and MooseFS
HDFS is the open-source realization of that design: a NameNode holds the namespace and the file→block map — “user data never flows through the NameNode” — while DataNodes store the blocks (128 MB) and serve reads and writes directly to clients. MooseFS applied the same master-plus-chunkservers split but exposed a full POSIX filesystem you mount, closing the gap back to the local-filesystem interface. These systems fixed what NFS and AFS could not: they stopped pretending one server owns a disk, and instead let an authoritative metadata service coordinate a scalable pool of data storage. What they still asked of you was to run that metadata master and that fleet of data servers yourself — which is exactly the operational burden CloudFS removes.Further Reading
- Sun’s Network File System (NFS) and The Andrew File System (AFS), from OSTEP.
- The Google File System (Ghemawat, Gobioff, Leung), Apache Hadoop / HDFS, and MooseFS.
How CloudFS Works
Source: https://developers.telnyx.com/docs/edge-compute/cloudfs/concepts/how-cloudfs-works.mdThis page is the destination of a short arc. If you want the reasoning behind the design, read the background first:
- Filesystems From First Principles — a filesystem is a metadata index over a pile of data blocks.
- Network Filesystems — why bolting a network onto a disk-owning server is brittle, and how GFS, HDFS, and MooseFS split an authoritative metadata service from a scalable pool of data storage.
How CloudFS Does It
CloudFS is built on JuiceFS, which — in its authors’ words — was “inspired by Google File System, HDFS and MooseFS.” JuiceFS takes the metadata/data split those systems proved at cluster scale and replaces each half with a managed cloud primitive, so you operate neither a metadata master nor a fleet of data servers:- The metadata index — the master’s job in GFS, the NameNode’s in HDFS — becomes a transactional database. The database provides strong consistency for the small, hot, correctness-critical half: an entry is committed or it is not, and every client reads the same tree. This is the direct answer to NFS’s stale-attribute cache and AFS’s callback bookkeeping — put the index in one consistent place that all clients share, rather than caching copies and trying to keep them in sync. It also inherits the database’s transactions: the crash-consistency machinery a local filesystem hand-builds as journaling — write-ahead log, commit, replay — is simply what the database already does, so a metadata change is one atomic transaction with no partial-update window and no
fsck-style recovery scan. - The data blocks — the chunkservers’ job — become object storage (Telnyx Cloud Storage). JuiceFS splits every file into a chunk → slice → block hierarchy and writes the blocks as ordinary objects; object storage supplies the durability and throughput for the large half. The blocks are opaque — you cannot reassemble a file from the bucket alone, because the index that orders them lives in the metadata database. Object storage also rewards writing new immutable objects over rewriting in place, so JuiceFS follows a log-structured discipline: each write becomes a new slice, never an overwrite, and a background compaction later merges overlapping slices and reclaims the garbage — exactly the cleaner a log-structured filesystem runs.
- There is no CloudFS server in the data path. JuiceFS is a “rich client”: like AFS’s client and MooseFS’s FUSE mount, all the filesystem logic — the directory tree, inode allocation, splitting files into blocks, caching — runs in the process that mounts the volume. But instead of caching whole files and chasing callbacks, it reads and writes the shared metadata database directly, so consistency comes from the database rather than from a promise a server has to remember. When you
juicefs mount, the client opens one connection to the metadata database and one to object storage, and serves POSIX calls from those two.
The Two Lanes
Concretely, a CloudFS mount talks to two backends over two independent lanes, each with its own credential. There is no CloudFS server in the request path — your client connects to both directly.The Metadata Lane
The client reaches metadata over the connection string CloudFS gives you asmeta_url:
- You connect to a managed metadata endpoint, not to the database directly. The public host
us-east-1.telnyxcloudfs.com:5432is a pooled front end to a per-filesystem metadata database (fs_<hex>). The database server itself is not directly reachable. - TLS is required. The connection uses
sslmode=require; there is no plaintext metadata path. - The
meta_tokenis the password. In themeta_urlabove, thecloudfs_tok_...embedded before the@is themeta_tokenused as the connection password. It is a managed, rotatable credential (see The Metadata Token Lifecycle) — not the underlying database’s own credential, which you never handle.
us-central-1 or us-west-1 filesystem still has its metadata host set to us-east-1.telnyxcloudfs.com. Always use the host embedded in meta_url.
Because metadata lives only in us-east-1, a client mounting from another region pays a network round-trip on every metadata operation, so metadata-heavy work (listing large trees, many small files) is slower the farther you mount from us-east-1. Data throughput is unaffected — that lane goes to your region’s storage endpoint.
The Data Lane
File contents go to a per-filesystem bucket namedcloudfs-fs-<hex> on Telnyx Cloud Storage, reached through the S3 endpoint for the filesystem’s region (s3_endpoint, e.g. https://us-east-1.telnyxcloudstorage.com). JuiceFS splits every file into 4 MiB block objects and writes them under chunks/… in that bucket; a 10 MiB file plus a small git repo, for example, lands as dozens of block objects. The blocks are opaque to S3 — reconstructing a file requires the chunk/slice index from the metadata lane.
That bucket lives in your own Telnyx Cloud Storage account — it shows up in your bucket list and is reachable with your TELNYX_API_KEY, exactly like any other bucket you own. But its contents are CloudFS’s internal state, not your files: the chunks/… objects are opaque 4 MiB JuiceFS blocks, and a small juicefs_uuid object holds the volume format. Do not delete, rename, move, or edit objects in a cloudfs-fs-* bucket by hand. An out-of-band change corrupts the filesystem — a missing or altered block cannot be reconstructed, and there is no fsck to repair it. Read and write your files through the mount, and leave the bucket to JuiceFS.
Authentication to the data lane reuses your account credentials, following the Telnyx Cloud Storage model:
- The S3 access-key is your
TELNYX_API_KEY. - The S3 secret-key is ignored — Telnyx Storage does not verify the SigV4 signature (see Cloud Storage authentication). You must still supply some non-empty secret, because JuiceFS’s AWS SDK rejects empty static credentials.
juicefs_uuid object and formats the volume (JuiceFS volume name cloudfs-fs-<hex>). Do not run juicefs format against a ready filesystem — it is already formatted, and re-formatting fails with cannot update volume name. Just mount. The one exception is a filesystem whose status is needs_format, which was provisioned without the final format step: format it once as described in Mounting, then mount.
Two Credentials, One API Key
Putting the lanes together, a mounting client holds exactly what it needs and nothing more:
The point of splitting the credentials this way is that the client never holds a raw database credential. It talks to the metadata endpoint with a managed
meta_token that Telnyx can rotate independently of the underlying metadata database, and it never connects to the database server directly. Your API key, meanwhile, only ever reaches object storage. Compromising a mount host exposes a rotatable metadata token and your (already-scoped) API key — not standing database credentials.
Create and rotate are the only responses that return the meta_token (and the token-bearing meta_url). GET detail returns meta_url without the token, and list returns neither. Store the token when you create the filesystem — there is no way to read it back.
Regions
You choose a data region at create time:us-central-1, us-east-1, or us-west-1. That region is required — there is no default — and it determines the S3 endpoint (s3_endpoint) and where the file blocks physically live. It is the only region choice you make.
Metadata is always in us-east-1. Picking us-west-1 for data does not move the metadata database; that filesystem’s metadata host is still us-east-1.telnyxcloudfs.com. Mount as close to us-east-1 as your data region allows if metadata latency matters to your workload.
The Metadata Token Lifecycle
Themeta_token is the one credential in the system designed to be rolled. Rotation is a control-plane action:
POST /v2/storage/cloudfs/{id}/actions/rotate-meta-token (Idempotency-Key required) issues a new meta_token and returns a new token-bearing meta_url. Rotation touches only the token — the metadata database and the S3 bucket are unchanged, so no data moves and no files are re-encrypted or re-keyed.
The cutover is connection-scoped, which makes rotation safe to run against a live filesystem:
- The old token stops authenticating on the next metadata connection — any new
juicefs mount(or reconnect) must use the newmeta_url. - An already-mounted client is unaffected on its existing connection. It keeps working with the connection it opened before rotation; you only need the new token the next time it reconnects.
meta_url is stored (secrets, deploy config) before your mounts next reconnect.
Filesystem Status
Each filesystem carries astatus:
The steady states are
ready, needs_format, and failed; provisioning and deleting are transitional. There is no soft-delete or trash lifecycle — deleted is terminal and permanent.
Further Reading
- JuiceFS — the open-source filesystem CloudFS is built on: architecture and how JuiceFS stores files.
- OSTEP on the ideas CloudFS reuses: Crash Consistency: FSCK and Journaling — why the metadata index belongs in a transactional database — and Log-structured File Systems — write-new-never-overwrite, and the cleaner behind JuiceFS compaction.
Next Steps
- Quick Start — Create a filesystem and mount it
- Mounting — The verified
juicefs mountrecipe - Concurrent Access — Many clients mounting one filesystem, and file locking
- API Reference — The six control-plane endpoints
- Overview — What CloudFS is and when to use it
Guides
Mounting a Filesystem
Source: https://developers.telnyx.com/docs/edge-compute/cloudfs/mount.mdA CloudFS filesystem is mounted with the JuiceFS Community Edition client: give it the metadata URL and S3 credentials below, and it exposes a POSIX filesystem at a mountpoint through FUSE. This page is the end-to-end mount recipe for each environment, verified against a live filesystem. If your host can’t do FUSE at all, serve the filesystem over WebDAV instead — no kernel support needed. If you haven’t created a filesystem yet, start with the Quick Start. For the two-lane architecture behind the credentials, see How CloudFS Works.
Prerequisites
- The JuiceFS Community Edition client. Install it per the JuiceFS docs. This page was verified end-to-end with JuiceFS CE 1.4.0.
- An existing CloudFS filesystem (create one), and the
meta_urlandmeta_tokenfrom its create response. The token is returned only at create (and on rotate) — if you didn’t store it, you cannot reconstruct it and must rotate to get a new one. - FUSE. A usable
/dev/fuseon Linux, or macFUSE on macOS. (Serving Without FUSE needs neither.)
Credentials the Client Needs
The client holds three things. None of them is a raw database password — the metadata token is the password, embedded in the URL.
The
meta_url returned by create already has the token inline as the password:
meta_url returned by GET /v2/storage/cloudfs/{id} is the same string without the token:
meta_token in as the password (postgres://fs_<hex>:<meta_token>@...). The host is always the region metadata host us-east-1.telnyxcloudfs.com — metadata is centralized there regardless of the filesystem’s data region.
Set the Environment
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY at mount time. Set them explicitly. Telnyx Cloud Storage authenticates on the access key alone and ignores the SigV4 signature, so the secret can be any non-empty string — see Cloud Storage authentication. An empty secret fails: JuiceFS’s AWS SDK rejects it with static credentials are empty.
The same environment also feeds Serving Without FUSE.
Do not run juicefs format against a filesystem whose status is ready. Provisioning already formats the volume (the bucket ships with a juicefs_uuid object and a fixed volume name), and re-formatting fails with cannot update volume name. The one exception is a filesystem in needs_format — see Formatting a needs_format filesystem.
Mount with FUSE
The first positional argument is the metadata URL; the second is the mountpoint. Mount in the background and write logs to a file so the mount doesn’t block your terminal — on success the command returns immediately and the filesystem is live at the mountpoint. Needs a usable/dev/fuse, which stock kernels have.
/tmp/juicefs.log for the mount status and any warnings.
The most portable way to mount — no FUSE install on the host, identical behavior everywhere. The container needs FUSE and the juicefs binary: run it privileged and pass the FUSE device through with --device /dev/fuse.
--privileged and --device /dev/fuse are what let FUSE mount inside the container. Without them the mount fails to open /dev/fuse. If you bake the juicefs binary and fuse into your own image, you can skip the install step and go straight to juicefs mount.
With macFUSE installed and its system extension approved, the recipe is the same — pick a mountpoint in your home directory:
--no-usage-report flag opts out of JuiceFS’s anonymous usage reporting. By default the JuiceFS client reports core metrics (such as its version) to the JuiceFS project on mount; it does not include user data. These docs pass --no-usage-report on every mount so CloudFS filesystems don’t phone home by default — drop the flag if you’d like to share usage data with the upstream project.
Formatting a needs_format Filesystem
If GET /v2/storage/cloudfs/{id} reports "status": "needs_format", the bucket and metadata database exist but the volume was never formatted, and mounting fails with database is not formatted, please run juicefs format ... first. This is the one case where you run juicefs format — once, then mount as normal:
<s3_endpoint> and <s3_bucket> come from the filesystem’s detail response, and the JuiceFS volume name must be the s3_bucket value (cloudfs-fs-<hex>) — any other name is rejected. Keep AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY exported (format probes the bucket over S3) and leave --access-key / --secret-key unset: the stored volume config then carries no credentials, same as a factory-formatted filesystem. Note that --no-usage-report is a mount flag — format doesn’t accept it.
Verify the Mount
The checks below are written for Linux with the/mnt/agentfs mountpoint. On macOS, substitute yours (e.g. ~/agentfs), check with mount | grep agentfs in place of mountpoint, and hash with md5 in place of md5sum.
git init and git commit inside the mountpoint behave as expected.
Unmount
META_URL brings all files back.
Troubleshooting
Next Steps
- Serving Without FUSE — serve the filesystem over WebDAV on hosts that can’t mount
- Concurrent Access — mount the same filesystem from many clients at once, and coordinate writers with locks
- How CloudFS Works — the metadata and data lanes, and what lives where
- API Reference — create, list, get, update, delete, and rotate the metadata token
- Overview — what CloudFS is and when to reach for it
Serving Without FUSE
Source: https://developers.telnyx.com/docs/edge-compute/cloudfs/serve.mdA WebDAV-served filesystem is not full POSIX. Everyday file operations work, but the POSIX surface a FUSE mount provides does not survive the HTTP hop. Good for: reading and writing files, shuttling them between machines, browsing in Finder, everyday
ls / cd / cp / mv / mkdir, and any app that speaks WebDAV directly.
No good for: git working trees (git init fails), executing binaries in place (noexec), coordinating writers with file locks (flock is local-only), or anything that needs faithful permissions and ownership. For those, mount with FUSE.
Mounting a filesystem goes through FUSE, and not every host has FUSE to give: a managed Mac whose MDM policy blocks macFUSE, a container you can’t run with --device /dev/fuse, a host where you aren’t root. The same JuiceFS client can serve the filesystem instead: juicefs webdav is an ordinary user-space process listening on a TCP port — it holds the same two backend connections a mount holds and exposes the filesystem as a WebDAV endpoint over HTTP, with no kernel support at all.
Serving is not mounting — no path on the host becomes the filesystem; clients speak HTTP to a port. On macOS you can then mount that endpoint with the OS’s built-in WebDAV client and get a Finder-visible volume anyway. A serve process is a full JuiceFS client, so it coexists with every other client of the filesystem — FUSE mounts elsewhere, many clients at once — with the same close-to-open consistency between clients as between mounts. Verified end-to-end with JuiceFS CE 1.4.0 against a live filesystem.
Prerequisites
- The JuiceFS Community Edition client. Install it per the JuiceFS docs.
- An existing CloudFS filesystem (create one), and the same environment a mount takes — the tokenized
META_URLplus theAWS_*pair. Set them per Set the Environment on the mount page.
Start the WebDAV Server
OK, service is ready on "127.0.0.1:9007" and returns. The filesystem is now an HTTP endpoint — round-trip a file to confirm:
127.0.0.1 — only processes on the same host can reach it. To serve beyond localhost, set WEBDAV_USER and WEBDAV_PASSWORD in the server’s environment before starting it; the server then returns 401 unless the request carries matching Basic credentials (curl -u agent:...). Basic auth over plain http:// sends the password — and your files — readable on the wire, so pair it with TLS (juicefs webdav serves HTTPS with --cert-file / --key-file) or keep the port reachable only over a private network or SSH tunnel.
--background daemonizes the server, which is convenient interactively. Under a supervisor (launchd, systemd, a container entrypoint), drop --background and run it in the foreground — the supervisor then owns restarts, and startup errors land in its logs instead of a detached daemon’s.
Mount the WebDAV Endpoint in Finder (macOS)
macOS ships its own WebDAV filesystem — it’s what Go → Connect to Server uses. It is part of the OS, so an MDM policy that blocks third-party system extensions (the reason macFUSE won’t install) doesn’t apply to it. Point it at the local server and you get a real mounted volume — a mount of the endpoint, one hop in front of CloudFS:http://127.0.0.1:9007. If Finder prompts for credentials against an anonymous server, connect as Registered User with any username and an empty password — the Guest option is rejected. Unmount with umount ~/CloudFS.
What Works Through the Mount — and What Doesn’t
Everyday file operations behave like a local directory:ls, cd, mkdir, cp, mv, cat, editing files, working in Finder — all verified against a live filesystem. But it is WebDAV underneath, not POSIX, and the difference shows at the edges:
- No executing in place. The volume is mounted
nodev,noexec,nosuid— you can read and write binaries, but running one from the mount fails withpermission denied. Copy it out first. - Listings lag a few seconds. Apple’s WebDAV client caches directory listings, so a file another client just wrote may take a moment (or a Finder refresh) to appear.
- Git working trees don’t work.
git initinside the mount fails writing.git/config(Invalid argument). Keep repositories on a FUSE mount, which handles them fine. - File locks coordinate nothing.
flockcalls succeed, but the lock is local to your machine — the cross-client lock coordination that FUSE mounts get through the shared metadata does not ride over WebDAV. Don’t rely on locks taken through this mount. - Permissions are cosmetic. Every entry appears owned by your local user with
-rwx------modes, whatever a POSIX client would see.
Troubleshooting
Next Steps
- Mounting a Filesystem — the FUSE recipe, and the environment setup this page reuses
- Concurrent Access — many clients on one filesystem, and what consistency they get
- How CloudFS Works — the metadata and data lanes every client connects to
Concurrent Access
Source: https://developers.telnyx.com/docs/edge-compute/cloudfs/concurrent-access.mdCloudFS is a shared filesystem: the same filesystem can be mounted by many clients at once — a fleet of agents, a set of containers, several hosts — and they read and write it concurrently. Because the metadata index lives in one consistent store that every client reads and writes directly (rather than each client keeping its own copy and reconciling later), all mounts converge on the same directory tree.
Mount the Same Filesystem on Many Clients
Every client mounts with the samemeta_url (token included) and the same TELNYX_API_KEY. There is nothing per-client to set up — a mount holds no server-side state — so you can add or remove clients at any time. Run the mount recipe on each host:
meta_url.
What One Client Sees of Another’s Writes
CloudFS gives close-to-open consistency, the standard for shared filesystems: when a client writes a file and closes it, other clients see the new contents the next time they open it. Directory operations — create, rename, delete — commit to the metadata store immediately and become visible to other clients within about a second (the lifetime of a client’s kernel metadata cache). With client A and client B both mounted at/mnt/shared:
Coordinating Writers on the Same File
Two clients writing the same file (or the same byte range) at the same time is the one case that needs coordination — as on any shared filesystem, uncoordinated overlapping writes resolve last-writer-wins. Use file locks: CloudFS supports both BSD locks (flock) and POSIX record locks (fcntl), and JuiceFS coordinates them across clients through the shared metadata. A lock held on one host blocks a conflicting lock on another.
flock exits non-zero and B’s command doesn’t run — so a fleet can serialize access to a shared resource (a worklog, a build output directory, a leader-election file) without any external coordinator.
Worked Example: Two Clients, One Filesystem
Two containers, each an independent client, mounting the same filesystem:Caveats
- Same-file, uncoordinated concurrent writes resolve last-writer-wins on overlapping regions. Use the locks above whenever more than one client may write the same file.
- Metadata latency. Every metadata operation — open, create, rename, lock — is a round-trip to
us-east-1(see The Metadata Lane). Coordination-heavy or many-small-file workloads run faster the closer clients mount to us-east-1; bulk data throughput is unaffected. - One credential set per filesystem. All clients share the same
meta_tokenand API key; there is no per-client scoping within a filesystem.
Next Steps
- Mounting a Filesystem — the full mount recipe each client runs
- How CloudFS Works — why one consistent metadata store makes shared access work
- Quick Start — create a filesystem and mount it
API Reference (CloudFS (Beta))
cloudfs filesystems
- List CloudFS filesystems: Lists the CloudFS filesystems for the authenticated user’s organization. Results use cursor-based pagination: fetch the next page by passing `meta.cursors.afte…
- Create a CloudFS filesystem: Creates a CloudFS filesystem. Provisioning is synchronous — typically a few seconds, up to a few minutes — and the filesystem is returned with status
ready,… - Get a CloudFS filesystem: Retrieves a CloudFS filesystem by its ID. The returned
meta_urlomits the credential — the metadata token is only ever returned by create and rotate-meta-tok… - Update a CloudFS filesystem: Updates a CloudFS filesystem. Only
namecan be changed; other fields are immutable and unknown fields are rejected with a400. Renaming to a name that alre… - Delete a CloudFS filesystem: Permanently deletes a CloudFS filesystem, removing its S3 bucket and its metadata database. Deletion is synchronous: the response returns the filesystem’s fina…
- Rotate the metadata token: Issues a new metadata access token for the filesystem and returns the full filesystem, including the new
meta_tokenand credential-bearingmeta_url. The pr…