new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Supabase · Storage · all subjects

storage/overview

60 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Supabase Storage key features

Supabase Storage is a robust, scalable solution for managing files of any size with fine-grained access controls and optimized delivery. It supports multi-protocol access including S3-compatible storage, RESTful API, and TUS resumable uploads. Files are served globally via CDN from over 285 cities worldwide. The service includes built-in image optimization for resizing, compressing, and transforming media files on the fly. Access control is managed through row-level security and custom policies. Multiple bucket types are supported for different use cases.

Logs Explorer for advanced Storage log filtering

The Logs Explorer is a separate tool from the SQL Editor that allows advanced filtering of Storage logs. It uses a subset of BigQuery SQL syntax rather than traditional SQL for querying the Storage logs dataset directly.

Query Storage logs for 4XX errors

To filter Storage logs for HTTP status codes 400-499, query the storage_logs table with a cross join on metadata, then on m.res, then on m.error, filtering where r.statusCode >= 400 and r.statusCode < 500. The query returns id, timestamp, event_message, statusCode, error message, and raw error. Example query: select id, storage_logs.timestamp, event_message, r.statusCode, e.message as errorMessage, e.raw as rawError from storage_logs cross join unnest(metadata) as m cross join unnest(m.res) as r cross join unnest(m.error) as e where r.statusCode >= 400 and r.statusCode < 500 order by timestamp desc limit 100;

Storage Logs dashboard access and basic filtering

The Storage Logs dashboard provides a way to examine all incoming request logs to the Storage service. You can filter by time and keyword searches using the dashboard interface.

Query Storage logs by IP address

To filter Storage logs by remote IP address, query the storage_logs table with a cross join on metadata, then on m.req, filtering where r.remoteAddress matches the desired IP address. The query returns id, timestamp, event_message, and remoteAddress. Example query: select id, storage_logs.timestamp, event_message, r.remoteAddress from storage_logs cross join unnest(metadata) as m cross join unnest(m.req) as r where r.remoteAddress in ("IP_ADDRESS") order by timestamp desc limit 100;

Storage logs metadata structure

Storage logs contain a metadata field with nested structures: m.res contains response information including statusCode and method, m.req contains request information including method and remoteAddress, and m.error contains error information including message and raw error details.

Query Storage logs by HTTP method

To filter Storage logs by HTTP method, query the storage_logs table with a cross join on metadata, then on m.req, filtering where r.method matches the desired method. The query returns id, timestamp, event_message, and method. Example query for POST requests: select id, storage_logs.timestamp, event_message, r.method from storage_logs cross join unnest(metadata) as m cross join unnest(m.req) as r where r.method in ("POST") order by timestamp desc limit 100;

MissingParameter error code (400)

The MissingParameter error with status code 400 means a required parameter is missing in the request. Resolution: Provide all required parameters in the request to fulfill the API's requirements. The message field will contain more details.

LockTimeout error code (423)

The LockTimeout error with status code 423 means a timeout occurred while waiting for a lock. The lock could not be acquired within the specified timeout. Resolution: Wait and try the request again.

S3Error error code

The S3Error indicates an error occurred related to Amazon S3. Resolution: Refer to Amazon S3 documentation or contact Supabase Support for assistance with resolving the S3 error.

SlowDown error code (503)

The SlowDown error with status code 503 means the request rate is too high and has been throttled. Resolution: Reduce the request rate or implement exponential backoff and retry mechanisms to handle throttling.

Legacy error format (429 too many requests)

The legacy error format returns status code 429 with error code 'too many requests', typically arising when a large number of clients are concurrently interacting with the Storage service and the pooler has reached its max_clients limit. Resolution: Increase the max_clients limits of the pooler or upgrade to a bigger project compute instance.

Legacy error format (544 database_timeout)

The legacy error format returns status code 544 with error code 'database_timeout', arising when a high number of clients are concurrently using the Storage service and Postgres doesn't have enough available connections. Resolution: Increase the pool_size limits of the pooler or upgrade to a bigger project compute instance.

Legacy error format (500 internal_server_error)

The legacy error format returns status code 500 with error code 'internal_server_error', occurring when there is an unhandled error. Resolution: File a support ticket to the Storage team.

DatabaseTimeout error code (504)

The DatabaseTimeout error with status code 504 means a timeout occurred while accessing the database. Resolution: Investigate database performance and increase the default pool size. If this error persists, upgrade your instance.

Storage error response format with error code and message

Storage errors are returned as JSON with the structure: {"code": "error_code", "message": "error_message"}. Error codes help with debugging and understanding what went wrong with requests.

InvalidRequest error code (400)

The InvalidRequest error with status code 400 means the request is not properly formed. Resolution: Review the request parameters and structure to ensure they meet the API's requirements. The error message will provide more details.

TenantNotFound error code (404)

The TenantNotFound error with status code 404 means the specified tenant does not exist. This indicates the Storage service had issues while provisioning. Resolution: Contact Supabase Support.

InternalError error code (500)

The InternalError error with status code 500 means an internal server error occurred. Resolution: Investigate server logs to identify the cause of the error. If you believe it is a Storage error, contact Supabase Support.

ResourceLocked error code (423)

The ResourceLocked error with status code 423 means the specified resource is locked. This resource cannot be altered while there is a lock. Resolution: Wait and try the request again.

DatabaseError error code (500)

The DatabaseError error with status code 500 means an error occurred while accessing the database. Resolution: Investigate database logs and system configuration to identify and address the database error.

Storage pricing charged by bucket asset size

Users are charged for the total size of all assets stored in their buckets. Charges are based on the aggregate storage consumed across all buckets in the project.

File metadata storage location

File metadata is stored separately from the actual files in the storage.buckets and storage.objects tables in your Postgres database. A complete backup requires backing up both the files and their metadata.

Call list_objects function via Supabase SDK

The list_objects Postgres function can be called via the Supabase SDK using: ```js const { data, error } = await supabase.rpc('list_objects', { bucketid: 'yourbucket', prefix: '', limit: 100, offset: 0, }) ```

supabase.storage.list() slows with many objects

The supabase.storage.list() method starts to slow down once you have a substantial number of objects. This occurs because the endpoint is generic and attempts to retrieve both folders and objects in a single query.

Create custom Postgres function to optimize object listing

If your application doesn't need the entire hierarchy computed, you can speed up drastically the query execution for listing objects by creating a custom Postgres function. This function queries the storage.objects table directly with specific filters instead of using the generic list() endpoint.

list_objects Postgres function for optimized listing

The following Postgres function can be created to efficiently list objects: ```sql create or replace function list_objects( bucketid text, prefix text, limits int default 100, offsets int default 0 ) returns table ( name text, id uuid, updated_at timestamptz, created_at timestamptz, last_accessed_at timestamptz, metadata jsonb ) as $$ begin return query SELECT objects.name, objects.id, objects.updated_at, objects.created_at, objects.last_accessed_at, objects.metadata FROM storage.objects WHERE objects.name like prefix || '%' AND bucket_id = bucketid ORDER BY name ASC LIMIT limits OFFSET offsets; end; $$ language plpgsql stable; ``` This function returns a table with columns: name (text), id (uuid), updated_at (timestamptz), created_at (timestamptz), last_accessed_at (timestamptz), and metadata (jsonb).

Call list_objects function via SQL

The list_objects Postgres function can be called directly via SQL: ```sql select * from list_objects('bucket_id', '', 100, 0); ``` Where the parameters are: bucket_id (string), prefix (string), limit (int, default 100), and offset (int, default 0).

Folders organize files in Supabase Storage

Folders are a way to organize your files, similar to how folders work on a computer. There is no right or wrong way to organize your files, and you can store them in whichever folder structure suits your project.

Files can be any media type including images, GIFs, and videos

Files in Supabase Storage can include any sort of media file. It is best practice to store files outside of your database because of their sizes. For security, HTML files are returned as plain text.

S3 ListObjects implementation details

ListObjects is implemented with support for query parameters: delimiter, encoding-type, marker, max-keys, prefix. Not supported: Request Payer (x-amz-request-payer), Bucket Owner (x-amz-expected-bucket-owner).

S3 ListObjectsV2 implementation details

ListObjectsV2 is implemented with support for query parameters: list-type, continuation-token, delimiter, encoding-type, fetch-owner, max-keys, prefix, start-after. Not supported: Request Payer (x-amz-request-payer), Bucket Owner (x-amz-expected-bucket-owner).

S3 DeleteObjects implementation details

DeleteObjects is implemented. Not supported: Multi-factor authentication (x-amz-mfa), Object Locking bypass-governance-retention, Request Payer (x-amz-request-payer), Bucket Owner (x-amz-expected-bucket-owner).

S3 CopyObject implementation details

CopyObject is implemented with support for operation metadata (x-amz-metadata-directive with partial support), system metadata (Content-Type, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Expires), and conditional operations (x-amz-copy-source, x-amz-copy-source-if-match, x-amz-copy-source-if-modified-since, x-amz-copy-source-if-none-match, x-amz-copy-source-if-unmodified-since). Not supported: ACL headers, Website redirect, all SSE-C headers, Request Payer, Tagging, Object Locking, Bucket Owner headers, Checksums.

Supabase Storage S3 protocol compatibility

Supabase Storage is compatible with the S3 protocol. You can use almost any S3 client to interact with Storage objects. Storage supports standard uploads, resumable uploads, and S3 uploads, and all these protocols are interoperable—you can upload with one protocol and list with another.

S3 versioning not supported

Supabase Storage does not enable S3's versioning capabilities for buckets. Deleted objects are permanently removed and cannot be restored.

S3 presigning with AWS Signature Version 4

Supabase Storage supports presigning URLs using query parameters via AWS Signature Version 4. This feature must be enabled by enabling the S3 connection via S3 protocol in the Settings page for Supabase Storage.

S3 bucket operations implemented

Implemented S3 bucket operations: ListBuckets, HeadBucket, CreateBucket, DeleteBucket, GetBucketLocation. Not implemented: DeleteBucketCors, GetBucketEncryption, GetBucketLifecycleConfiguration, GetBucketCors, PutBucketCors, PutBucketLifecycleConfiguration. HeadBucket and GetBucketLocation do not support Bucket Owner or x-amz-expected-bucket-owner. CreateBucket does not support ACL, x-amz-acl, x-amz-grant-* headers, Object Locking, or Bucket Owner headers. DeleteBucket does not support Bucket Owner or x-amz-expected-bucket-owner.

Storage metadata stored in Postgres schema

Supabase Storage uses Postgres to store metadata regarding buckets and objects. Users can use RLS (Row-Level Security) policies for access control. This data is stored in a dedicated schema within your project called `storage`.

All storage operations must go through the API

All operations on Storage tables, including uploading, copying, moving, and deleting, should exclusively go through the API. Users should consider all records in Storage tables as read-only in SQL. Deleting metadata directly does not remove the object in the underlying storage provider, resulting in the object being inaccessible but still incurring charges.

Do not modify the storage schema directly

Users should refrain from making alterations to the storage schema and treat it as read-only. Modifications could potentially clash with future Supabase updates, leading to downtime.

Vector bucket local development with Supabase CLI

Vector buckets can be developed and tested in a local environment using the Supabase CLI. The latest version of the CLI must be installed to access this feature. This allows building and iterating on vector search applications without deploying to a live environment.

Vector bucket local development engine

In local development, vector buckets use pg_vector as the underlying storage engine. The hosted version uses S3Vectors as the storage engine for vectors, which is optimized for large-scale vector storage and similarity search. Performance and behavior may differ between local and cloud environments, but the API remains consistent between both.

Enable vector storage in config.toml

To enable vector bucket functionality in local development, add the following configuration to the config.toml file: [storage.vector] enabled = true

Vector buckets overview and purpose

Vector buckets are specialized storage containers optimized for vector data. Unlike traditional databases optimized for transactional queries, vector buckets use specialized indexing and distance metrics to perform fast similarity searches across millions of embeddings. They are built on S3-compatible storage and provide high-performance semantic search capabilities for AI and machine learning applications.

JavaScript SDK queryVectors full example

const index = supabase.storage.vectors.from('embeddings').index('documents-openai') const { data, error } = await index.queryVectors({ queryVector: { float32: [0.1, 0.2, 0.3] }, topK: 5, returnDistance: true, returnMetadata: true, }) data.vectors.forEach((result, rank) => { console.log(`${rank + 1}. ${result.metadata?.title}`) console.log(` Similarity score: ${result.distance.toFixed(4)}`) })

JavaScript SDK semantic search full example

const queryEmbedding = await openai.embeddings.create({ model: 'text-embedding-3-small', input: query }) const queryVector = queryEmbedding.data[0].embedding const { data, error } = await supabase.storage.vectors .from('embeddings') .index('documents-openai') .queryVectors({ queryVector: { float32: queryVector }, topK, returnDistance: true, returnMetadata: true }) return data.vectors.map((result) => ({ id: result.key, title: result.metadata?.title, similarity: 1 - result.distance, metadata: result.metadata }))

Vector similarity search with Python SDK

Use `supabase.storage.vectors().from_('bucket-name').index('index-name').query()` to perform similarity search. Parameters include: query_vector (dict with 'float32' key containing embedding array), topK (number of results), return_distance (boolean), return_metadata (boolean). Results accessed via results.vectors where each result has key, distance, and metadata attributes.

Vector similarity search with SQL using S3 Vector Wrapper

Query vectors using the S3 Vector Wrapper with SQL: `SELECT key, metadata FROM s3_vectors.index_name WHERE data <==> '[...]'::embd ORDER BY embd_distance(data) ASC LIMIT 5;`. The `<===>` operator performs distance-based similarity search. Use `embd_distance(data)` function to get distance values. This is the only similarity search algorithm supported by vector buckets.

Semantic search by embedding query text

To perform semantic search, first embed the query text using an external API like OpenAI's embeddings endpoint (e.g., 'text-embedding-3-small' model), then use the resulting embedding vector in queryVectors(). This allows searching by text similarity rather than raw vector values.

Filtered similarity search with metadata

Vector queries support filtering by metadata fields using a filter object. JavaScript example: filter: { category: 'electronics', in_stock: true, price: { $lte: 500 } }. Python example: filter={'category': 'electronics', 'in_stock': True, 'price': {'$lte': 500}}. SQL uses WHERE clauses: AND (metadata->>'category') = 'electronics' AND (metadata->>'price')::numeric <= 500.

Retrieve specific vectors by keys

Use `index.getVectors()` (JavaScript) or `index.get()` (Python) to retrieve specific vectors by their keys. Parameters: keys (array of vector keys), returnData (boolean to include embeddings), returnMetadata (boolean to include metadata). SQL equivalent: `SELECT key, data, metadata FROM s3_vectors.index_name WHERE key IN ('key-1', 'key-2');`

List vectors with pagination

Use `index.listVectors()` (JavaScript) or `index.list()` (Python) to paginate through vectors. Parameters: maxResults (max results per page), nextToken (pagination token), returnData (set false for faster response), returnMetadata (boolean). SQL pagination uses LIMIT and OFFSET: `SELECT key, metadata FROM s3_vectors.index_name ORDER BY key ASC LIMIT 100 OFFSET 0;`

Hybrid search combining vectors and relational data

Query vectors with topK: 100, then fetch additional details from relational tables using the metadata doc_id field with `.in('id', [...doc_ids...])`. SQL equivalent uses LEFT JOIN: `SELECT v.key, d.id, d.full_text FROM s3_vectors.index v LEFT JOIN public.documents d ON v.metadata->>'doc_id' = d.id::text WHERE v.data <==> '[...]'::embd ORDER BY embd_distance(v.data) ASC;`

RAG (retrieval-augmented generation) workflow with vectors

RAG workflow: (1) Embed user query using OpenAI embeddings API with model 'text-embedding-3-small', (2) Query vector index with the embedding and topK: 5, (3) Extract metadata.content from results and join into context string, (4) Pass context to LLM system prompt for augmented generation. This retrieves relevant documents to provide context for LLM responses.

Product recommendation using vector similarity

Query vector index with user embedding, applying metadata filter (e.g., in_stock: true), returning topK results. Map results to extract product metadata fields like product_id, name, price. Calculate similarity score as (1 - distance) to show relevance percentage.

Vector bucket feature status

Vector buckets are in alpha. Expect rapid changes, limited features, and possible breaking updates. Feature is subject to refinement.

Only supported similarity search algorithm for vectors

Vector buckets and their Foreign Data Wrappers (FDW) support only one similarity search algorithm: the `<===>` distance operator. This is the only distance metric available.

Distance to similarity conversion formula

Convert distance scores to similarity percentages using the formula: similarity = 1 - distance. Results are ranked with lowest distance representing highest similarity. Display as percentage: (similarity * 100).toFixed(1)%

Python SDK query full example

index = supabase.storage.vectors().from_('embeddings').index('documents-openai') results = index.query( query_vector={'float32': [0.1, 0.2, 0.3]}, topK=5, return_distance=True, return_metadata=True ) for rank, result in enumerate(results.vectors, 1): print(f'{rank}. {result.metadata.get("title") if result.metadata else "N/A"}') if result.distance is not None: print(f' Similarity score: {result.distance:.4f}')

Give your agent this brain