Files
supabase/apps/docs/content/guides/queues/quickstart.mdx
Ivan VasilovandJordi Enric 56de26fe22 chore: Migrate the monorepo to use Tailwind v4 (#45318)
This PR migrates the whole monorepo to use Tailwind v4:
- Removed `@tailwindcss/container-queries` plugin since it's included by
default in v4,
- Bump all instances of Tailwind to v4. Made minimal changes to the
shared config to remove non-supported features (`alpha` mentions),
- Migrate all apps to be compatible with v4 configs,
- Fix the `typography.css` import in 3 apps,
- Add missing rules which were included by default in v3,
- Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot
of classes
- Rename all misnamed classes according to
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all
apps.

---------

Co-authored-by: Jordi Enric <jordi.err@gmail.com>
2026-04-30 10:53:24 +00:00

335 lines
9.4 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Quickstart
subtitle: 'Learn how to use Supabase Queues to add and read messages'
---
{/* <!-- vale off --> */}
This guide is an introduction to interacting with Supabase Queues via the Dashboard and official client library. Check out [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.
### Pull-Based Queue
A pull-based Queue is a Message storage and delivery system where consumers actively fetch Messages when they're ready to process them - similar to constantly refreshing a webpage to display the latest updates. Our pull-based Queues process Messages in a First-In-First-Out (FIFO) manner without priority levels.
### Message
A Message in a Queue is a JSON object that is stored until a consumer explicitly processes and removes it, like a task waiting in a to-do list until someone checks and completes it.
### Queue types
Supabase Queues offers three types of Queues:
- **Basic Queue**: A durable Queue that stores Messages in a logged table.
- **Unlogged Queue**: A transient Queue that stores Messages in an unlogged table for better performance but may result in loss of Queue Messages.
- **Partitioned Queue** (_Coming Soon_): A durable and scalable Queue that stores Messages in multiple table partitions for better performance.
## Create Queues
To get started, navigate to the [Supabase Queues](/dashboard/project/_/integrations/queues/overview) Postgres Module under Integrations in the Dashboard and enable the `pgmq` extension.
<Admonition type="note">
`pgmq` extension is available in Postgres version 15.6.1.143 or later.
</Admonition>
<Image
alt="Supabase Dashboard Integrations page, showing the Queues Postgres Module"
src={{
dark: '/docs/img/queues-quickstart-install.png',
light: '/docs/img/queues-quickstart-install.png',
}}
width={2064}
height={1720}
/>
On the [Queues page](/dashboard/project/_/integrations/queues/queues):
- Click **Add a new queue** button
<Admonition type="note">
If you've already created a Queue click the **Create a queue** button instead.
</Admonition>
- Name your queue
<Admonition type="note">
Queue names can only be lowercase and hyphens and underscores are permitted.
</Admonition>
- Select your [Queue Type](#queue-types)
<Image
alt="Create a Queue from the Supabase Dashboard"
src={{
dark: '/docs/img/queues-quickstart-create.png',
light: '/docs/img/queues-quickstart-create.png',
}}
className="max-w-lg mx-auto!"
width={1456}
height={1420}
/>
### What happens when you create a queue?
Every new Queue creates two tables in the `pgmq` schema. These tables are `pgmq.q_<queue_name>` to store and process active messages and `pgmq.a_<queue_name>` to store any archived messages.
A "Basic Queue" will create `pgmq.q_<queue_name>` and `pgmq.a_<queue_name>` tables as logged tables.
However, an "Unlogged Queue" will create `pgmq.q_<queue_name>` as an unlogged table for better performance while sacrificing durability. The `pgmq.a_<queue_name>` table will still be created as a logged table so your archived messages remain safe and secure.
## Expose Queues to client-side consumers
Queues, by default, are not exposed over Supabase Data API and are only accessible via Postgres clients.
However, you may grant client-side consumers access to your Queues by enabling the Supabase Data API and granting permissions to the Queues API, which is a collection of database functions in the `pgmq_public` schema that wraps the database functions in the `pgmq` schema.
This is to prevent direct access to the `pgmq` schema and its tables (RLS is not enabled by default on any tables) and database functions.
To get started, navigate to the Queues [Settings page](/dashboard/project/_/integrations/queues/settings) and toggle on “Expose Queues via PostgREST”. Once enabled, Supabase creates and exposes a `pgmq_public` schema containing database function wrappers to a subset of `pgmq`'s database functions.
<Image
alt="Screenshot of Queues settings with toggle to expose to PostgREST"
src={{
dark: '/docs/img/queues-quickstart-settings.png',
light: '/docs/img/queues-quickstart-settings.png',
}}
width={2140}
height={1642}
/>
### Enable RLS on your tables in `pgmq` schema
For security purposes, you must enable Row Level Security (RLS) on all Queue tables (all tables in `pgmq` schema that begin with `q_`) if the Data API is enabled.
You’ll want to create RLS policies for any Queues you want your client-side consumers to interact with.
<Image
alt="Screenshot of creating an RLS policy from the Queues settings"
src={{
dark: '/docs/img/queues-quickstart-rls.png',
light: '/docs/img/queues-quickstart-rls.png',
}}
width={2130}
height={1508}
/>
### Grant permissions to `pgmq_public` database functions
On top of enabling RLS and writing RLS policies on the underlying Queue tables, you must grant the correct permissions to the `pgmq_public` database functions for each Data API role.
The permissions required for each Queue API database function:
| **Operations** | **Permissions Required** |
| ------------------- | ------------------------ |
| `send` `send_batch` | `Select` `Insert` |
| `read` `pop` | `Select` `Update` |
| `archive` `delete` | `Select` `Delete` |
To manage your queue permissions, click on the Queue Settings button.
<Image
alt="Screenshot of accessing queue settings"
src={{
dark: '/docs/img/queues-quickstart-queue-settings.png',
light: '/docs/img/queues-quickstart-queue-settings.png',
}}
width={2150}
height={1192}
/>
Then enable the required roles permissions.
<Image
alt="Screenshot of configuring API access for roles from the Queues settings"
src={{
dark: '/docs/img/queues-quickstart-roles.png',
light: '/docs/img/queues-quickstart-roles-light.png',
}}
width={1271}
height={1315}
/>
<Admonition type="note">
`postgres` and `service_role` roles should never be exposed client-side.
</Admonition>
### Enqueueing and dequeueing messages
Once your Queue has been created, you can begin enqueueing and dequeueing Messages.
<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="js"
queryGroup="language"
>
<TabPanel id="js" label="JavaScript">
```tsx
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = 'supabaseURL'
const supabaseKey = 'supabaseKey'
const supabase = createClient(supabaseUrl, supabaseKey)
const QueuesTest: React.FC = () => {
//Add a Message
const sendToQueue = async () => {
const result = await supabase.schema('pgmq_public').rpc('send', {
queue_name: 'foo',
message: { hello: 'world' },
sleep_seconds: 30,
})
console.log(result)
}
//Dequeue Message
const popFromQueue = async () => {
const result = await supabase.schema('pgmq_public').rpc('pop', { queue_name: 'foo' })
console.log(result)
}
return (
<div className="p-6">
<h2 className="text-2xl font-bold mb-4">Queue Test Component</h2>
<button
onClick={sendToQueue}
className="bg-blue-500 text-white px-4 py-2 rounded-sm hover:bg-blue-600 mr-4"
>
Add Message
</button>
<button
onClick={popFromQueue}
className="bg-blue-500 text-white px-4 py-2 rounded-sm hover:bg-blue-600"
>
Pop Message
</button>
</div>
)
}
export default QueuesTest
```
</TabPanel>
<$Show if="sdk:dart">
<TabPanel id="dart" label="Dart">
```dart
import 'package:supabase_flutter/supabase_flutter.dart';
final supabase = Supabase.instance.client;
// Add a Message
Future<void> sendToQueue() async {
final result = await supabase.schema('pgmq_public').rpc('send', params: {
'queue_name': 'foo',
'message': {'hello': 'world'},
'sleep_seconds': 30,
});
print(result);
}
// Dequeue Message
Future<void> popFromQueue() async {
final result = await supabase.schema('pgmq_public').rpc('pop', params: {
'queue_name': 'foo',
});
print(result);
}
```
</TabPanel>
</$Show>
<$Show if="sdk:swift">
<TabPanel id="swift" label="Swift">
```swift
import Supabase
let supabase = SupabaseClient(
supabaseURL: URL(string: "supabaseURL")!,
supabaseKey: "supabaseKey"
)
// Add a Message
func sendToQueue() async throws {
let result = try await supabase
.schema("pgmq_public")
.rpc("send", params: [
"queue_name": AnyJSON.string("foo"),
"message": AnyJSON.object(["hello": "world"]),
"sleep_seconds": AnyJSON.integer(30)
])
.execute()
print(result)
}
// Dequeue Message
func popFromQueue() async throws {
let result = try await supabase
.schema("pgmq_public")
.rpc("pop", params: ["queue_name": "foo"])
.execute()
print(result)
}
```
</TabPanel>
</$Show>
<$Show if="sdk:python">
<TabPanel id="python" label="Python">
```python
from supabase import create_client, Client
supabase_url = "supabaseURL"
supabase_key = "supabaseKey"
supabase: Client = create_client(supabase_url, supabase_key)
# Add a Message
def send_to_queue():
result = supabase.schema("pgmq_public").rpc(
"send",
{
"queue_name": "foo",
"message": {"hello": "world"},
"sleep_seconds": 30,
}
).execute()
print(result)
# Dequeue Message
def pop_from_queue():
result = supabase.schema("pgmq_public").rpc(
"pop",
{"queue_name": "foo"}
).execute()
print(result)
```
</TabPanel>
</$Show>
</Tabs>