TMA CloudTMA Cloud
Concepts

File System

File system architecture and organization in TMA Cloud.

File system architecture and organization in TMA Cloud.

File Structure

Hierarchical Organization

  • Root Level: User's root directory
  • Folders: Nested folder structure
  • Files: Stored within folders or root

File Metadata

  • ID: Unique identifier (stable across operations)
  • Name: File or folder name
  • Type: 'file' or 'folder'
  • Size: File size in bytes
  • MIME Type: Actual MIME type detected from file content (not from extension)
  • Parent ID: Parent folder reference
  • Path: The storage key, not a user-visible path
  • User ID: The account the item belongs to
  • Last Access Time: When the item was last read (accessed_at), shown in the UI as "Last opened"
  • Shared At: When the item most recently became shared (shared_at); null while the item is not shared

File Operations

Supported Operations

  • Upload: Add new files
  • Download: Retrieve files
  • Create Folder: Create new directories
  • Move: Move files/folders
  • Copy: Duplicate files/folders
  • Rename: Change file/folder names
  • Delete: Move to trash
  • Star: Mark as favorite
  • Share: Create share links

Large File Handling

  • Streaming: Files streamed without loading into memory
  • Upload: Files encrypted and streamed directly to the bucket
  • Download: Files streamed from storage to client; single-file downloads support HTTP Range (partial content) for seeking
  • ZIP Archives: Archive entries are read through a database cursor and streamed one at a time, keeping database pages and open storage streams bounded
  • Rename: Change file/folder names

Performance

  • Streaming prevents memory exhaustion for large files (>1GB)
  • Rename operations update database metadata without moving stored objects
  • Copy operations are queued on the background worker, use server-side object-store copy with four transfers at most, and read folder trees once before batched inserts
  • File lists use stable cursor batches and load continuously as the user scrolls. Only visible grid/list rows plus a small overscan are rendered
  • Folder sizes and descendant counts are maintained by database triggers. Size sorting uses those stored totals and the matching page-order index instead of walking a folder tree during a listing
  • No file size limits imposed by memory constraints

Path Management

  • Renaming or moving an item changes its parent_id and name, not its storage key, so no stored object is touched
  • Stored object keys are validated as flat keys without path separators or traversal sequences

Last Access Time

Every file and folder carries an accessed_at timestamp, surfaced in the UI as Last opened in Get Info and as a sort option in the file list. It answers "when was this last read", which modified cannot, since modified only moves when the contents change.

What Counts as Reading

ActionUpdates
Downloading a fileThat file
Downloading a folder as ZIPThe folder and everything in it
Bulk downloadEvery item in the archive
Opening a document in OnlyOfficeThat file
Reading a file through a share linkThat file
Opening a folder in the file listThe folder only, not its contents
Uploading or replacing a fileThat file

Listing a folder marks the folder and leaves its children alone. This matches how Windows treats directory enumeration, and it keeps the value meaningful: if browsing past a file counted as opening it, every file in a folder you visit would look recently used.

Searching, viewing Get Info, renaming, moving, starring and sharing do not count as reads.

Write Behavior

Recording a read on every request would turn each read into a database write. Two rules keep that cost bounded, both taken from how filesystems handle the same problem:

  • One-hour window. Once an item's timestamp is written, further reads of it are ignored until the window passes. NTFS guarantees its last-access time only to within an hour for the same reason; Linux's relatime uses a comparable rule.
  • Buffered writes. Updates accumulate in memory and are written in one batched statement every 10 seconds, so no read waits on a write. Linux's lazytime works the same way.

The effect is at most one write per item per hour, batched. The number of statements is set by the flush interval rather than by how many users are reading, so it does not grow with traffic. Timestamps may lag by the flush interval plus the window, which is why the value is documented as approximate.

Set ACCESS_TIME_TRACKING=0 to switch the feature off. See Environment Variables for the tuning knobs.

On the Cloud Drive

The mounted Windows drive reports this value as the NTFS LastAccessTime, so Explorer's Date accessed column reflects it. The other three NTFS timestamps come from the modification time. Windows writes LastAccessTime back when a handle closes; the drive accepts and discards those writes, because the server decides what counts as a read. See Desktop App.

Storage

Physical Storage

  • S3: Files stored in S3-compatible object storage. Database stores object key.
  • Bucket configuration is required before starting the backend.
  • Original filenames preserved in database

File Encryption

  • Files encrypted with AES-256-GCM in Google Tink's AES-GCM-HKDF-STREAMING format (the AES256_GCM_HKDF_1MB scheme)
  • Each newly encrypted object version uses a random data key (DEK). FILE_ENCRYPTION_KEY is the key-encryption key (KEK) that wraps the DEK; a server-side logical copy reuses the source ciphertext and wrapped DEK
  • Each object has a 40-byte header (a random salt and nonce prefix) followed by 1 MB segments, each sealed with its own authentication tag. The per-file encryption key is derived from the DEK with HKDF-SHA256
  • Segments make stored objects seekable: a download serves an HTTP Range request by fetching and decrypting only the overlapping segments, so a large file opens without reading all of it
  • Automatic decryption on download
  • Rotate FILE_ENCRYPTION_KEY with rotate-kek.js, which only rewraps the stored DEKs and never re-encrypts the objects. See CLI Commands

Storage Limits

  • Per-user storage limits
  • Configurable by administrators
  • Real-time usage tracking

Trash System

Soft Delete

  • Files moved to trash (not deleted)
  • deleted_at timestamp set
  • Restorable within retention period

Automatic Cleanup

  • Trash items deleted after 15 days
  • Background worker handles cleanup
  • Permanent deletion after retention
  • Manual permanent deletion and Empty Trash run on background worker
  • PostgreSQL pg_trgm extension for fuzzy text matching
  • GIN index on file names for fast searches
  • Prefix matching for short queries
  • Indexed trigram matching for longer queries
  • Real-time search results
  • User-scoped searches

On this page