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/cdn

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

Storage includes global CDN

Supabase Storage includes a global CDN that serves assets from over 285 cities worldwide for lightning-fast performance.

Cache hit status values in Supabase Storage CDN

Cache hits in Supabase Storage are determined via the metadata.response.headers.cf_cache_status key in the Logs Explorer. Any value corresponding to HIT, STALE, REVALIDATED, or UPDATING is categorized as a cache hit.

Cache miss status values in Supabase Storage CDN

Cache misses in Supabase Storage are determined via the metadata.response.headers.cf_cache_status key in the Logs Explorer. Values corresponding to MISS, NONE/UNKNOWN, EXPIRED, BYPASS, or DYNAMIC are categorized as cache misses.

Query cache misses from edge_logs

To find the top cache misses from edge_logs, query the edge_logs table filtering for requests to /storage/v1/object with GET method and cf_cache_status in (MISS, NONE/UNKNOWN, EXPIRED, BYPASS, DYNAMIC). The query is: select r.path as path, r.search as search, count(id) as count from edge_logs as f cross join unnest(f.metadata) as m cross join unnest(m.request) as r cross join unnest(m.response) as res cross join unnest(res.headers) as h where starts_with(r.path, '/storage/v1/object') and r.method = 'GET' and h.cf_cache_status in ('MISS', 'NONE/UNKNOWN', 'EXPIRED', 'BYPASS', 'DYNAMIC') group by path, search order by count desc limit 50;

Query cache hit ratio over time

To determine cache hit ratio over time, query edge_logs grouped by hourly timestamp, calculating the proportion of requests with cf_cache_status in (HIT, STALE, REVALIDATED, UPDATING) to total requests. The query is: select timestamp_trunc(timestamp, hour) as timestamp, countif(h.cf_cache_status in ('HIT', 'STALE', 'REVALIDATED', 'UPDATING')) / count(f.id) as ratio from edge_logs as f cross join unnest(f.metadata) as m cross join unnest(m.request) as r cross join unnest(m.response) as res cross join unnest(res.headers) as h where starts_with(r.path, '/storage/v1/object') and r.method = 'GET' group by timestamp order by timestamp desc;

Cache metrics accessed via Logs Explorer

Cache metrics for Supabase Storage are accessed through the Logs Explorer in the dashboard. The cf_cache_status header in edge_logs contains the cache status for each request.

JavaScript SDK purge single object example

import { createClient } from '@supabase/supabase-js' const supabase = createClient('your_project_url', 'your_secret_key') async function purgeCachedObject() { const { data, error } = await supabase.storage .from('bucket_name') .purgeCache('folder_name/file_name.png') if (error) { // Handle error } else { console.log(data.message) // 'success' } }

C# SDK purge single object example

var response = await supabase.Storage .From("bucket_name") .PurgeCache("folder_name/file_name.png");

Purge cache for entire bucket

To invalidate all cached objects in a bucket, you can purge the entire bucket's cache. This is useful when performing bulk updates or major changes to your storage bucket.

JavaScript SDK purge bucket cache example

import { createClient } from '@supabase/supabase-js' const supabase = createClient('your_project_url', 'your_secret_key') async function purgeBucketCache() { const { data, error } = await supabase.storage.purgeBucketCache('bucket_name') if (error) { // Handle error } else { console.log(data.message) // 'success' } }

cURL purge bucket cache example

curl -X DELETE "https://{your_project_ref}.supabase.co/storage/v1/cdn/bucket_name" \ -H "apikey: {your_secret_key}" If using legacy jwt keys use this header: Authorization: Bearer {your_service_role_jwt}

C# SDK purge bucket cache example

var response = await supabase.Storage.PurgeBucketCache("bucket_name");

Cache purge does not affect browser cache

Purging the CDN cache does not affect browser caches. If users have the asset cached locally in their browser, they will continue to see the cached version until the browser cache expires based on the cacheControl value set during upload.

CDN cache propagation time

After purging the cache, it can take up to 60 seconds for the invalidation to propagate across all CDN edge nodes worldwide. During this time, some users may still receive cached content depending on which edge node they are routed to.

After cache purge, next request served from origin

Once purged, the next request for that object will be served from the origin server, and the CDN cache will be repopulated.

Smart CDN automatic cache invalidation

With Smart CDN enabled, Supabase Storage automatically invalidates the cache when files are updated or deleted. Manual cache purging is available for scenarios where you need to ensure updates propagate immediately or clear the cache for debugging purposes.

Cache purge API requires secret key

Cache purging requires the secret key. The server rejects calls made with the legacy anon key or a user JWT. Secret keys must never be exposed in client-side code.

CDN cache purge availability

CDN cache purge is available for Pro Plan and above.

Purge cache for single object

To purge the CDN cache for a specific file, provide the exact path to the object. The operation does not support wildcards or recursion; you must specify the complete path of the file you want to invalidate.

Reusing signed URLs improves cache hit rates

If you re-use the same signed URL across multiple requests, subsequent requests are served from cache. If the asset has no meaningful per-user access restriction, prefer a public bucket. It results in higher cache hit rates and removes the need to manage signed URL generation entirely.

Smart CDN enabled by default for Pro Plan and above

Smart CDN caching is automatically enabled for Pro Plan and above.

Smart CDN asset metadata synchronization to edge

With Smart CDN caching enabled, the asset metadata in the database is synchronized to the edge. This automatically revalidates the cache when the asset is changed or deleted.

Smart CDN cache hit rate with query string shielding

Smart CDN achieves a greater cache hit rate by shielding the origin server from asset requests that remain unchanged, even when different query strings are used in the URL.

Smart CDN caches assets for as long as possible

When Smart CDN is enabled, the asset is cached on the CDN for as long as possible.

cacheControl option for browser cache duration

You can control how long assets are stored in the browser using the cacheControl option when uploading a file. Smart CDN caching works with all types of storage operations including signed URLs.

CDN cache invalidation takes up to 60 seconds

When a file is updated or deleted, the CDN cache is automatically invalidated to reflect the change including transformed images. It can take up to 60 seconds for the CDN cache to be invalidated as the asset metadata has to propagate across all the data-centers around the globe.

Browser cache not automatically updated when CDN cache invalidated

When an asset is invalidated at the CDN level, browsers may not update their cache. This is where cache eviction comes into play.

Upload frequently updated assets to different path

If you have assets that undergo frequent updates, it is advisable to upload the new asset to a different path. This approach ensures that you always have the most up-to-date asset accessible.

Set shorter browser TTL for assets that might be deleted

If you anticipate that your asset might be deleted, it is advisable to set a shorter browser Time-to-Live (TTL) value using the cacheControl option. The default TTL is typically set to 1 hour, which is generally a reasonable default value.

Bypass CDN cache using unique query string

If you need to ensure assets refresh directly from the origin server and bypass the cache, you can achieve this by adding a unique query string such as cacheNonce to the URL. For example, you can use a URL like /storage/v1/object/sign/profile-pictures/cat.jpg?cacheNonce=1 with a long browser cache. To update the picture, increment the cacheNonce query parameter in the URL, like /storage/v1/object/sign/profile-pictures/cat.jpg?cacheNonce=2. The CDN will recognize it as a new object and fetch the updated version from the origin.

Signed URLs cached at CDN edge with unique token

Signed URLs are the primary way to serve assets from private buckets to end users. With Smart CDN enabled, signed URL responses are cached at the CDN edge like any other storage request. Each signed URL contains a unique token query parameter (?token=...). Smart CDN treats each unique token as a separate cache key, meaning the first request with any given signed URL results in a cache miss, and only subsequent requests using that exact same URL will receive a cache hit. Two different signed URLs for the same object, even if generated seconds apart, each maintain their own independent cache entry.

Generating new signed URL on every request prevents cache hits

If you generate a new signed URL on every request, the cache will never be warm and every request hits the origin.

Revoking token does not purge CDN cache entry

Revoking or expiring a token does not purge its CDN cache entry. The cached response persists at the edge until the cache duration expires.

Deleting object invalidates all cached entries across tokens

Deleting the object invalidates all cached entries for that object across all tokens. This can take up to a minute to propagate.

Token expiry and cache TTL are independent

Token expiry (expiresIn) and the object's response cache TTL (cacheControl) are independent. Once a response is cached at the edge, that cached response can continue to be served for the same signed URL until the CDN cache duration expires, even if the token in that URL has already expired.

Delete object to cut off asset access, not token expiry alone

If you need to cut off access to an asset, delete the object from the bucket rather than relying on token expiry alone.

High cache-control value reduces egress

Setting a high cache-control value ensures assets stay in the user's browser for an extended period, decreasing the need to download from the server repeatedly. Using the browser cache can effectively lower egress since the asset remains stored in the user's browser after the initial download.

Smart CDN achieves higher cache hit rate

By leveraging the Smart CDN, you can achieve a higher cache hit rate and therefore lower egress costs, as Supabase charges less for cached egress.

Free Plan bandwidth limit

Free Plan Organizations in Supabase have a limit of 10 GB of bandwidth total, comprised of 5 GB cached and 5 GB uncached. This limit is calculated by the sum of all data transferred from Supabase servers to the client, including data from the database, storage, and functions.

Query to check storage egress requests

Use this SQL template in Logs Explorer to analyze storage requests: select request.method as http_verb, request.path as filepath, (responseHeaders.cf_cache_status = 'HIT') as cached, count(*) as num_requests from edge_logs cross join unnest(metadata) as metadata cross join unnest(metadata.request) as request cross join unnest(metadata.response) as response cross join unnest(response.headers) as responseHeaders where (path like '%storage/v1/object/%' or path like '%storage/v1/render/%') and request.method = 'GET' group by 1, 2, 3 order by num_requests desc limit 100; This query filters for GET requests to storage object and render endpoints, groups by HTTP verb, filepath, and cache status, and returns the number of requests for each.

Calculate egress from request count and file size

To calculate storage egress, multiply the number of requests for each file by the size of that file in bytes. Sum the results for all files to get total egress. For example, if a 3 MB file is downloaded 100 times, that is 300 MB of egress.

Get file size using curl

Run curl -s -w "%{size_download}\n" -o /dev/null "https://my_project.supabase.co/storage/v1/object/bucket_name/file_path" to get the file size in bytes. This fetches the file without saving it locally and returns only the size_download variable.

Cache status indicator in edge logs

The responseHeaders.cf_cache_status field in edge logs indicates whether a request was cached (value 'HIT') or not. This is useful for separating cached bandwidth (counted within the 5 GB cached limit) from uncached bandwidth (counted within the 5 GB uncached limit).

CDN architecture for Supabase Storage

All assets uploaded to Supabase Storage are cached on a Content Delivery Network (CDN). CDNs are geographically distributed sets of servers or nodes which cache content from an origin server. For Supabase Storage, the origin is the storage server running in the same region as the project.

CDN benefits: performance, security, and availability

CDNs improve latency for users around the world. Beyond performance, CDNs help with security and availability by mitigating Distributed Denial of Service (DDoS) and other application attacks.

CDN cache miss and cache hit behavior

When a user requests an object and the CDN node does not have it cached, the node pings the origin server to retrieve it. This is a cache miss. When a subsequent user in the same region requests the same object, it is served directly from the CDN cache. This is a cache hit.

CDN cache eviction policy

CDNs might evict objects from their cache if the objects have not been requested for a while from a specific region. Even with a very long cache control duration set, objects will be removed from the CDN cache if no user from that region requests them.

Cache status header cf-cache-status

The cache status of a particular request is sent in the cf-cache-status header. A cache status of MISS indicates that the CDN node did not have the object in its cache and had to ping the origin to get it. A cache status of HIT indicates that the object was sent directly from the CDN.

Public buckets have better cache hit rates than private buckets

Objects in public buckets do not require any authorization to access. This leads to a better cache hit rate compared to private buckets because the same cached object can be served to any user.

Private bucket caching: per-user permission checks reduce cache hits

For private buckets, permissions for accessing each object are checked on a per-user level. If two different users access the same object in a private bucket from the same region, it results in a cache miss for both users since they might have different security policies attached to them.

Public bucket caching: multiple users see cache hits

If two different users access the same object in a public bucket from the same region, it results in a cache hit for the second user because no per-user authorization checks are needed.

Give your agent this brain