Skip to main content

File Storage

File Storage makes it easy to implement file upload in your app, store files from and send files to third-party APIs, and to serve dynamic files to your users. All file types are supported.

Security model

File IDs, like Id<"_storage">, are safe to store in your tables and pass through Convex functions. They identify stored files, but they are not direct download URLs.

File URLs generated by storage.getUrl() are different: anyone with the URL can access the file without another app-level authorization check. The only way to revoke a file URL is by deleting the file.

Key implications:

  • Access control happens before the URL is shared: You can choose who receives a file URL, but you cannot prevent them from reusing or sharing it.
  • Shared URLs are revoked by deleting the file: If you still need to serve the file, upload it again and share the new URL only with authorized users.
  • Changing access to the same file requires app-level checks: If a user's access can change over time, use an HTTP action to check permissions before returning file bytes. HTTP action responses are limited to 20MB, so they aren't a fit for serving larger files through Convex.

If you need file URLs that automatically expire after some time, consider the Cloudflare R2 component. Use Convex File Storage URLs only when bearer URL access is acceptable for your use case.

Features

  • Upload files to store them in Convex and reference them in your database documents
  • Store files generated or fetched from third-party APIs
  • Serve files via URL
  • Delete files stored in Convex
  • Access file metadata

You can manage your stored files on the dashboard.

Examples: File Storage with HTTP Actions, File Storage with Queries and Mutations