diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
index f4479bb3cc278..53963fb288310 100644
--- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
+++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
@@ -1390,7 +1390,13 @@ export const queues: NavMenuConstant = {
{
name: 'Getting Started',
url: undefined,
- items: [{ name: 'Quickstart', url: '/guides/queues/quickstart' }],
+ items: [
+ { name: 'Quickstart', url: '/guides/queues/quickstart' },
+ {
+ name: 'Consuming Messages with Edge Functions',
+ url: '/guides/queues/consuming-messages-with-edge-functions',
+ },
+ ],
},
{
name: 'References',
diff --git a/apps/docs/content/guides/queues/consuming-messages-with-edge-functions.mdx b/apps/docs/content/guides/queues/consuming-messages-with-edge-functions.mdx
new file mode 100644
index 0000000000000..8a890895fe688
--- /dev/null
+++ b/apps/docs/content/guides/queues/consuming-messages-with-edge-functions.mdx
@@ -0,0 +1,109 @@
+---
+title: Consuming Supabase Queue Messages with Edge Functions
+subtitle: 'Learn how to consume Supabase Queue messages server-side with a Supabase Edge Function'
+---
+
+This guide helps you read & process queue messages server-side with a Supabase Edge Function. Read [Queues API Reference](/docs/guides/queues/api) for more details on our API.
+
+## Concepts
+
+Supabase Queues is a pull-based Message Queue consisting of three main components: Queues, Messages, and Queue Types. You should already be familiar with the [Queues Quickstart](/docs/guides/queues/quickstart).
+
+### Consuming messages in an Edge Function
+
+This is a Supabase Edge Function that reads 5 messages off the queue, processes each of them, and deletes each message when it is done.
+
+```tsx
+import 'jsr:@supabase/functions-js/edge-runtime.d.ts'
+import { createClient } from 'npm:@supabase/supabase-js@2'
+
+const supabaseUrl = 'supabaseURL'
+const supabaseKey = 'supabaseKey'
+
+const supabase = createClient(supabaseUrl, supabaseKey)
+const queueName = 'your_queue_name'
+
+// Type definition for queue messages
+interface QueueMessage {
+ msg_id: bigint
+ read_ct: number
+ vt: string
+ enqueued_at: string
+ message: any
+}
+
+async function processMessage(message: QueueMessage) {
+ //
+ // Do whatever logic you need to with the message content
+ //
+ // Delete the message from the queue
+ const { error: deleteError } = await supabase.schema('pgmq_public').rpc('delete', {
+ queue_name: queueName,
+ msg_id: message.msg_id,
+ })
+
+ if (deleteError) {
+ console.error(`Failed to delete message ${message.msg_id}:`, deleteError)
+ } else {
+ console.log(`Message ${message.msg_id} deleted from queue`)
+ }
+}
+
+Deno.serve(async (req) => {
+ const { data: messages, error } = await supabase.schema('pgmq_public').rpc('read', {
+ queue_name: queueName,
+ sleep_seconds: 0, // Don't wait if queue is empty
+ n: 5, // Read 5 messages off the queue
+ })
+
+ if (error) {
+ console.error(`Error reading from ${queueName} queue:`, error)
+ return new Response(JSON.stringify({ error: error.message }), {
+ status: 500,
+ headers: { 'Content-Type': 'application/json' },
+ })
+ }
+
+ if (!messages || messages.length === 0) {
+ console.log('No messages in workflow_messages queue')
+ return new Response(JSON.stringify({ message: 'No messages in queue' }), {
+ status: 200,
+ headers: { 'Content-Type': 'application/json' },
+ })
+ }
+
+ console.log(`Found ${messages.length} messages to process`)
+
+ // Process each message that was read off the queue
+ for (const message of messages) {
+ try {
+ await processMessage(message as QueueMessage)
+ } catch (error) {
+ console.error(`Error processing message ${message.msg_id}:`, error)
+ }
+ }
+
+ // Return immediately while background processing continues
+ return new Response(
+ JSON.stringify({
+ message: `Processing ${messages.length} messages in background`,
+ count: messages.length,
+ }),
+ {
+ status: 200,
+ headers: { 'Content-Type': 'application/json' },
+ }
+ )
+})
+```
+
+Every time this Edge Function is run it:
+
+1. Read 5 messages off the queue
+2. Call the `processMessage` function
+3. At the end of `processMessage`, the message is deleted from the queue
+4. If `processMessage` throws an error, the error is logged. In this case, the message is still in the queue, so the next time this Edge Function runs it reads the message again.
+
+You might find this kind of setup handy to run with [Supabase Cron](/docs/guides/cron). You can set up Cron so that every N number of minutes or seconds, the Edge Function will run and process a number of messages off the queue.
+
+Similarly, you can invoke the Edge Function on command at any given time with [`supabase.functions.invoke`](/docs/guides/functions/quickstart-dashboard#usage).
diff --git a/apps/docs/spec/supabase_js_v2.yml b/apps/docs/spec/supabase_js_v2.yml
index 249d310b83cbd..169464ae0fc3d 100644
--- a/apps/docs/spec/supabase_js_v2.yml
+++ b/apps/docs/spec/supabase_js_v2.yml
@@ -1197,14 +1197,14 @@ functions:
isSpotlight: false
code: |
```js
- const { error } = await supabase.auth.signOut('local')
+ const { error } = await supabase.auth.signOut({ scope: 'local' })
```
- id: sign-out-other-sessions
name: Sign out (other sessions)
isSpotlight: false
code: |
```js
- const { error } = await supabase.auth.signOut('others')
+ const { error } = await supabase.auth.signOut({ scope: 'others' })
```
- id: verify-otp
title: 'verifyOtp()'
diff --git a/apps/studio/components/interfaces/DiskManagement/fields/DiskSizeField.tsx b/apps/studio/components/interfaces/DiskManagement/fields/DiskSizeField.tsx
index 9b6057676a281..5cb2a24a83f2a 100644
--- a/apps/studio/components/interfaces/DiskManagement/fields/DiskSizeField.tsx
+++ b/apps/studio/components/interfaces/DiskManagement/fields/DiskSizeField.tsx
@@ -88,7 +88,7 @@ export function DiskSizeField({
const mainDiskUsed = Math.round(((diskUtil?.metrics.fs_used_bytes ?? 0) / GB) * 100) / 100
return (
-