Skip to main content
Supabase provides PostgreSQL with a built-in REST API, authentication, and real-time features, perfect for rapid AI agent development.

Quick Start

1

Choose Connection Mode

Supabase offers two connection methods:
2

Set Environment Variables

# For REST API mode
export SUPABASE_URL="https://your-project.supabase.co"
export SUPABASE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

# Or for direct PostgreSQL mode  
export SUPABASE_DATABASE_URL="postgresql://postgres:pass@db.xxx.supabase.com:5432/postgres"
3

Test Conversation

# Start conversation
result = agent.start("I'm working on a chatbot project using Supabase")
print(result)

# Later session - memory persists
result = agent.start("What project was I working on?") 
print(result)  # "You were working on a chatbot project using Supabase"

Installation

# Install Supabase client
pip install supabase

Connection Modes

REST API Mode

Uses Supabase’s REST API with automatic schema generation:
from praisonaiagents import Agent

agent = Agent(
    name="REST Agent",
    instructions="You use Supabase REST API for persistence.",
    db={
        "database_url": "https://xxx.supabase.co",
        "supabase_key": "eyJhbGci...",  # anon or service_role key
    }
)

# Tables are created automatically via REST API
result = agent.start("Hello from Supabase REST!")
Required Tables (auto-created):
-- Create in Supabase SQL Editor if not using auto-creation
CREATE TABLE praison_sessions (
    session_id TEXT PRIMARY KEY,
    user_id TEXT,
    agent_id TEXT,
    name TEXT,
    state JSONB,
    metadata JSONB,
    created_at DOUBLE PRECISION,
    updated_at DOUBLE PRECISION
);

CREATE TABLE praison_messages (
    id TEXT PRIMARY KEY,
    session_id TEXT REFERENCES praison_sessions(session_id),
    role TEXT NOT NULL,
    content TEXT,
    tool_calls JSONB,
    metadata JSONB,
    created_at DOUBLE PRECISION
);

Direct PostgreSQL Mode

Uses standard PostgreSQL connection through Supabase’s pooler:
from praisonaiagents import Agent

agent = Agent(
    name="Direct Agent",
    instructions="You use direct PostgreSQL for persistence.",
    db={"database_url": "postgresql://postgres:pass@db.xxx.supabase.com:6543/postgres"}
)

# Standard PostgreSQL tables with auto-retry for paused projects
result = agent.start("Hello from Supabase PostgreSQL!")

Configuration Options

OptionREST ModeDirect ModeDescription
database_urlhttps://xxx.supabase.copostgresql://...Supabase URL
supabase_key✅ RequiredAPI key (anon or service_role)
max_retries33Retries for paused project recovery
retry_delay2.00.5Base delay between retries
auto_create_tablesTrueTrueCreate tables automatically

Usage Patterns

Environment-Based Setup

import os
from praisonaiagents import Agent

# REST API mode - auto-detects from environment
agent = Agent(
    name="Auto Agent",
    instructions="You auto-configure from environment.",
    db=True  # Uses SUPABASE_URL + SUPABASE_KEY
)

Manual REST Configuration

from praisonai.persistence.conversation.supabase import SupabaseConversationStore
from praisonaiagents import Agent

store = SupabaseConversationStore(
    url="https://your-project.supabase.co",
    key="eyJhbGci...",
    max_retries=5,  # Extra retries for paused projects
    retry_delay=3.0  # 3 second delays
)

agent = Agent(name="Manual Agent", db=store)

Full Lifecycle Example

import os
from praisonai import ManagedAgent, LocalManagedConfig  
from praisonaiagents import Agent

# Phase 1: Create agent with Supabase REST
managed = ManagedAgent(
    provider="local",
    db={
        "database_url": os.environ["SUPABASE_URL"],
        "supabase_key": os.environ["SUPABASE_KEY"]
    },
    config=LocalManagedConfig(
        model="gpt-4o-mini",
        name="Supabase Demo",
        system="You are a helpful assistant with Supabase persistence."
    )
)

agent = Agent(name="User", backend=managed)

# Store conversation data
result1 = agent.run("I'm building a real-time chat app with Supabase")
print(f"Agent: {result1}")

result2 = agent.run("The app needs user auth and database subscriptions")
print(f"Agent: {result2}")

# Phase 2: Save and simulate project pause (free tier)
session_data = managed.save_ids()
del agent, managed  # Simulate pause

# Phase 3: Resume after project wake-up
managed2 = ManagedAgent(
    provider="local",
    db={
        "database_url": os.environ["SUPABASE_URL"],
        "supabase_key": os.environ["SUPABASE_KEY"]
    }
)
managed2.resume_session(session_data["session_id"])

agent2 = Agent(name="User", backend=managed2) 
result3 = agent2.run("What kind of app am I building?")
print(f"Resumed Agent: {result3}")
# Should recall: real-time chat app with auth and subscriptions

Supabase-Specific Features

Paused Project Recovery

Free tier projects auto-pause after 1 week of inactivity. PraisonAI handles wake-up automatically:
from praisonai.persistence.conversation.supabase import SupabaseConversationStore

store = SupabaseConversationStore(
    url="https://paused-project.supabase.co",
    key="eyJ...",
    max_retries=5,  # Extra retries for wake-up
    retry_delay=3.0  # Longer delays for project start
)

# First request may take 30-60 seconds if project was paused
# Subsequent requests are fast

Row Level Security (RLS)

Enable RLS in Supabase for multi-tenant agents:
-- Enable RLS on tables
ALTER TABLE praison_sessions ENABLE ROW LEVEL SECURITY;
ALTER TABLE praison_messages ENABLE ROW LEVEL SECURITY;

-- Policy: Users can only access their own sessions
CREATE POLICY "Users can access own sessions" ON praison_sessions
    FOR ALL USING (user_id = auth.uid()::text);

-- Policy: Users can access messages from their sessions
CREATE POLICY "Users can access own messages" ON praison_messages  
    FOR ALL USING (
        session_id IN (
            SELECT session_id FROM praison_sessions WHERE user_id = auth.uid()::text
        )
    );
# Use service_role key for admin access, or implement user auth
agent = Agent(
    name="Multi-Tenant Agent",
    db={
        "database_url": "https://xxx.supabase.co",
        "supabase_key": "eyJ..."  # service_role key bypasses RLS
    }
)

Real-time Subscriptions

Listen to conversation changes in real-time:
import asyncio
from supabase import create_client

async def listen_to_conversations():
    supabase = create_client(
        "https://your-project.supabase.co",
        "eyJhbGci..."
    )
    
    def on_message(payload):
        print(f"New message: {payload}")
    
    # Subscribe to new messages
    supabase.table("praison_messages").on("INSERT", on_message).subscribe()
    
    # Keep listening
    await asyncio.sleep(3600)  # Listen for 1 hour

# Run in background
asyncio.create_task(listen_to_conversations())

Best Practices

  • REST API: Best for rapid prototyping, automatic pausing recovery, built-in auth
  • Direct PostgreSQL: Better performance, lower latency, standard SQL features
# REST: Easy setup, handles paused projects
rest_agent = Agent(db={"database_url": "https://xxx.supabase.co", "supabase_key": "..."})

# Direct: Better for production, lower latency  
direct_agent = Agent(db={"database_url": "postgresql://postgres:pass@db.xxx.supabase.com:6543/postgres"})
Free tier projects pause after 1 week. Design for graceful wake-up:
from praisonai.persistence.conversation.supabase import SupabaseConversationStore

# Optimize for paused project recovery
store = SupabaseConversationStore(
    url="https://project.supabase.co",
    key="eyJ...",
    max_retries=10,  # More retries for wake-up
    retry_delay=5.0   # Longer delays
)
Service role keys bypass Row Level Security. Use them only for admin operations:
# Anon key (limited permissions)
public_agent = Agent(db={"supabase_key": "eyJhbGci..."})  

# Service role (full access) - use carefully!
admin_agent = Agent(db={"supabase_key": "eyJhbGci..."})  # service_role key
Track your Supabase usage:
  • Database size: Conversation history grows over time
  • API requests: REST calls count toward monthly limits
  • Bandwidth: File uploads/downloads if using storage
Set up usage alerts in the Supabase dashboard.

Environment Variables

VariableModeFormatExample
SUPABASE_URLRESThttps://xxx.supabase.cohttps://abcdefgh.supabase.co
SUPABASE_KEYRESTJWT tokeneyJhbGciOiJIUzI1NiIs...
SUPABASE_DATABASE_URLDirectpostgresql://...postgresql://postgres:pass@db.xxx.supabase.com:5432/postgres
OPENAI_API_KEYBothsk-...sk-1234567890abcdef...

Troubleshooting

Project Paused Error

If you get “project is paused” errors:
# Wait 30-60 seconds for project to wake up, or upgrade to Pro plan
store = SupabaseConversationStore(max_retries=10, retry_delay=10.0)

API Key Permissions

Ensure your API key has the right permissions:
# Check key type in Supabase dashboard
# anon key: Limited to RLS policies
# service_role key: Full database access

SSL Connection Issues

For direct PostgreSQL mode, ensure SSL:
# Add SSL to connection string
db_url = "postgresql://postgres:pass@db.xxx.supabase.com:6543/postgres?sslmode=require"

Cloud Databases Overview

Compare all cloud database providers

Real-time Features

Build real-time AI applications