Reading files
File reading is available in queries, mutations, and actions viactx.storage.
getUrl
Get a URL for downloading a file.Id<'_storage'>
required
The ID of the file in storage.
string | null
A URL which fetches the file via HTTP GET, or
null if the file no longer exists.The GET response includes a standard HTTP Digest header with a SHA-256 checksum.getMetadata (deprecated)
Get metadata for a file.ctx.db.system.get("_storage", storageId) instead:
Id<'_storage'>
required
The ID of the file.
FileMetadata | null
Writing files
File writing is available in mutations viactx.storage.
generateUploadUrl
Generate a short-lived URL for uploading a file.string
A short-lived URL for uploading a file via HTTP POST.The client should POST the file as the request body. The response will be JSON containing the newly allocated
storageId:delete
Delete a file from storage.Id<'_storage'>
required
The ID of the file to delete.
getUrl() will return 404 errors.
Action-specific methods
In actions,ctx.storage has additional methods not available in mutations.
get
Download a file as a Blob.Id<'_storage'>
required
The ID of the file to download.
Blob | null
A Blob containing the file contents, or
null if the file doesn’t exist.store
Upload a Blob directly to storage.Blob
required
The Blob to store.
Id<'_storage'>
The ID of the newly stored file.
generateUploadUrl() instead.
File metadata
File metadata is stored in the_storage system table. Query it like any other table:
Common patterns
Upload workflow
Typical file upload flow:- Client requests upload URL:
- Client uploads file:
- Client saves to database:
Image gallery
File processing in actions
Delete file with cleanup
Best practices
Store metadata separately
Create a table to store file metadata (name, description, owner, etc.) and reference the
storageId. Don’t rely solely on the _storage system table.Clean up deleted files
When deleting database records that reference files, also delete the files from storage to avoid orphaned files.
Validate file types
Check file types and sizes on the client before uploading, and validate again in your mutation after upload.
Use actions for processing
Process files (resize images, extract text, etc.) in actions where you can use Node.js libraries.
Set appropriate content types
Set the
Content-Type header when uploading to ensure files are served with the correct MIME type.