This was my first reaction when Supabase announced their new Queue, Cron and Background Tasks in an Edge Function features.
Let me show you why this is such a big deal.
The Old World: Juggling Multiple Services
Picture this: You're building an (AI) app that needs to handle long-running processes, like AI-powered audio transcription. Until now, you had to piece together a puzzle of different services:
- Queue management with Bull or Trigger.dev
- A separate hosting platform for your background jobs (ex: Render, Railway)
- Redis for job state management
- And of course, Supabase for your main database
I experienced this while building AutoRepurpose AI - a tool that transforms YouTube videos into engaging social media content. The process involves:
- Extracting video subtitles
- Creating and storing embeddings in Supabase (PostgreSQL)
- Generating tailored social posts using these embeddings
For these tasks, I had to set up Bull on a Node.js instance hosted on Railway, plus Redis for managing the background processes.
The New World: Supabase Queue Changes Everything
Now, everything lives under one roof. No more context switching between services. No more managing multiple platforms. Just pure, streamlined efficiency.
Here's all you need to implement background processing with Supabase:
- Add items to your queue
- Create an edge function to process queued items
- Set up a cron job to trigger the processing
Let's see how this looks in code ✨:
Add a queue item: React component (Next.js)
const supabase = createClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{ db: { schema: "pgmq_public" } }
);
const sendToQueue = async () => {
await supabase.rpc("send", {
queue_name: "ai-background-job",
message: { userId, videoId },
});
};
return <button onClick={sendToQueue}>Create a new project</button>
ai-process edge function (Supabase Edge Functions)
import { createClient } from "https://esm.sh/@supabase/supabase-js@2.47.7";
import process from "node:process";
import type { Database } from "../supabase.ts";
const supabase = createClient<Database>(
process.env.SUPABASE_URL!,
process.env.SUPABASE_ANON_KEY!,
);
const supabasePgmqSchema = createClient<Database>(
process.env.SUPABASE_URL!,
process.env.SUPABASE_ANON_KEY!,
{ db: { schema: "pgmq_public" } },
);
Deno.serve(async (req) => {
const queueToProcess = await supabasePgmqSchema.rpc("pop", {
queue_name: "ai-background-job",
});
if (
queueToProcess.error || !queueToProcess.data ||
!Array.isArray(queueToProcess.data)
) {
return new Response(
JSON.stringify({ success: false }),
{ headers: { "Content-Type": "application/json" }, status: 500 },
);
}
const { userId, videoId } = queueToProcess.data[0].message as {
userId: string;
videoId: string;
};
// Fetch the transcription of the video, generate social posts,
// and save them in the database in the background
EdgeRuntime.waitUntil(processAIStuff({ userId, videoId }));
return new Response(
JSON.stringify({ success: true }),
{ headers: { "Content-Type": "application/json" } },
);
});
Set up a cron job
The new cron interface is quite straightforward. Just a few clicks in the dashboard, and you're done:
The Complete Backend Package
Supabase now offers everything you need in one platform:
- Queuing system
- Simple, powerful cron jobs
- Edge Functions with serverless computing and background task capabilities
- authentication
- PostgreSQL database with superpowers
They didn't just add a missing piece - they completed the backend puzzle. As developers, we can now focus on building features instead of managing infrastructure.
Supabase truly has become the backend that eats backends! ⚡️
Top comments (2)
I've used pg_cron before to trigger jobs that run as Edge Functions. Now, Queue was exactly the missing piece I needed!
Yes! We were able to use corn with pg_cron but now they have a UI for it + Queue!!