Limits
Default limits enforced by the reference LoonFS server.
Limits are deployment-specific. LoonFS deployments should tune their limits based on their unique constraints. The reference server is built around a safe set of limits that serve as a reasonable lower bound, but can be increased and tuned as needed.
Complying servers should publish the values they enforce as a response to GET /v0/capabilities. Clients should use that response instead of assuming any universal defaults.
Transfers
Section titled “Transfers”| Capability limit | Default | Meaning |
|---|---|---|
upload.service_proxied.max_content_bytes | 256 MiB | Largest service-proxied upload body. |
download.service_proxied.max_content_bytes | 256 MiB | Largest file returned through a service-proxied content read. |
upload.service_proxied.max_concurrent_requests | 8 | Proxied uploads the server accepts concurrently. |
download.service_proxied.max_concurrent_requests | 16 | Proxied content reads the server accepts concurrently. |
upload.direct_put.max_content_bytes | provider-dependent | Largest object the deployment’s provider accepts in one presigned direct_put. |
upload.complete.max_request_body_bytes | 8 MiB | Largest upload-completion JSON body, primarily bounding multipart part metadata. |
The service streams proxied uploads and downloads. These byte limits are not maximum file sizes: a deployment may support larger files using direct uploads, multipart uploads, and direct download grants.
upload.direct_put.max_content_bytes is the exception: it is the provider’s own single-request ceiling rather than anything the service buffers, so it is typically far larger than upload.service_proxied.max_content_bytes, and it is advertised only when the deployment knows it. A claim above it is answered with content_too_large when the upload begins, rather than being signed into a write the provider would reject.
Commits
Section titled “Commits”| Capability limit | Default | Meaning |
|---|---|---|
commit.max_operations | 4,096 | Filesystem operations in one commit. |
commit.max_preconditions | 1,024 | Request-level preconditions checked before operations. |
commit.max_inline_content_bytes_per_operation | 65,536 bytes | Decoded bytes per inline file value when inline content is enabled. |
commit.max_content_tokens | 4,096 | Content-preparation tokens carried by one commit. |
commit.max_external_content_refs | 4,096 | Distinct external content references named by one commit. |
commit.max_message_bytes | 4,096 bytes | UTF-8 byte length of the optional commit message. |
commit.max_request_body_bytes | 2 MiB | Largest commit request body, including any inline file content. |
access.max_principals_per_request: 64 principals per request by default.
Snapshots
Section titled “Snapshots”| Capability limit | Default | Meaning |
|---|---|---|
snapshot.max_ttl_ms | 86,400,000 ms (1 day) | Largest TTL accepted when creating or extending a snapshot. |
snapshot.max_lifetime_ms | 604,800,000 ms (7 days) | Latest expiry allowed relative to the snapshot’s original creation time. |
snapshot.max_live_per_namespace | 16 | Most concurrent live, unexpired snapshots in one namespace. |
“Extension” measures its requested TTL from the server’s current time and never moves the expiry beyond snapshot.max_lifetime_ms from creation. For example, the max_lifetime_ms value cannot be “cheated” by constantly extending. See Snapshots.
Pagination and search
Section titled “Pagination and search”| Capability limit | Default | Meaning |
|---|---|---|
pagination.default_limit | 1,000 | Items returned when a standard paged request omits limit. |
pagination.max_limit | 1,000 | Largest accepted standard page size. |
query.grep.default_limit | 1,000 | Matches returned when a grep request omits limit. |
query.grep.max_limit | 1,000 | Largest accepted grep page size. |
query.grep.scan_budget_files | 4,096 | Files a plan-less allow_scan query may scan. |
query.grep.tail_budget_files | 512 | Unindexed revisions a query may scan before reporting index lag. |
The query.grep.* limits are advertised only when the deployment serves the optional grep query capability.
Maintenance
Section titled “Maintenance”| Capability limit | Default | Meaning |
|---|---|---|
maintenance.gc.min_grace_window_ms | 1,335,000 ms | Smallest accepted garbage-collection grace window: 22 minutes, 15 seconds. |
Attributes
Section titled “Attributes”These protocol-wide constraints bound the key/value metadata one inode may carry. Every limit counts logical UTF-8 bytes, so the encoding that carries a map never changes what a caller may store. See Attributes.
| Attribute constraint | Maximum | Meaning |
|---|---|---|
| Attribute key length | 128 UTF-8 bytes | Largest single attribute key. |
| Attribute value length | 4,096 UTF-8 bytes | Largest string value. |
| Attribute entries | 100 | Entries in one inode’s attribute map. |
| Attribute map size | 65,536 UTF-8 bytes | Total size of one inode’s attribute map. |
Paths and namespace size
Section titled “Paths and namespace size”These protocol-wide path constraints apply across all deployments. These constraints are enforced for interoperability reasons, not for performance.
| Path constraint | Maximum | Meaning |
|---|---|---|
| Display-name length | 255 UTF-8 bytes | Largest stored name for one path component. |
| Canonical absolute-path length | 4,096 UTF-8 bytes | Largest complete canonical path. |
| Path depth | 128 components | Deepest nesting an absolute path may express. |
LoonFS does not impose a fixed inode-count ceiling. Practical scale depends on metadata shape, maintenance cadence, cache sizing, and workload.
Commit throughput is a function of commit.max_operations and the object store’s conditional-write behavior. For example, GCS documents one write per second to the same object name, (R2 rate-limits these concurrent writes as well).