Skip to main content

Supabase vs Appwrite in 2026: Which Open Source BaaS?

·OSSAlt Team
supabaseappwritebaasfirebasecomparison
Share:

Supabase vs Appwrite in 2026: Open Source BaaS Platforms Compared

TL;DR

Both Supabase and Appwrite are open source Firebase replacements with auth, database, storage, and real-time built in. Supabase is built on PostgreSQL — full SQL access, row-level security, vector search, and the largest open source BaaS community. Appwrite is database-agnostic with a document model and 14 function runtimes — more opinionated, but more flexible about language choice for server-side logic. For most developers: Supabase wins on database power and ecosystem. For teams running multi-language functions or preferring a document model: Appwrite makes a strong case.

Key Takeaways

  • Supabase (Apache-2.0, 76K+ stars) is built on PostgreSQL — full SQL, RLS, PostgREST auto-API, pgvector, and database branching
  • Appwrite (BSD-3-Clause, 46K+ stars) uses a document model on MariaDB with 14 function runtimes (Node.js, Python, PHP, Ruby, Go, Swift, Dart, Bun, Deno, and more)
  • Firebase's Blaze plan costs $0.05/GB/month storage + $0.12/GB bandwidth — a growing app pays $200-500+/month
  • Supabase's real-time uses PostgreSQL logical replication (truly database-driven); Appwrite's real-time is event-based through the application layer
  • Appwrite has 12+ client SDKs including more mobile platform SDKs; Supabase has JS, Flutter, Swift, Kotlin, Python
  • Both support 30+ OAuth providers, email/password auth, magic links, and anonymous sessions

The Firebase Replacement Problem

Firebase's problem isn't the product — it's the pricing trajectory. The free Spark plan is genuinely useful, which creates adoption. Then as an app grows, costs become unpredictable: storage at $0.05/GB/month, Firestore reads at $0.06/100K, writes at $0.18/100K, bandwidth at $0.12/GB. A mobile app with 50K daily active users doing moderate database activity can easily hit $300-600/month.

Self-hosted BaaS eliminates per-operation pricing. One VPS costs the same whether you do 1 million or 100 million database reads.

The more interesting question is which self-hosted BaaS fits your architecture.


Supabase — PostgreSQL-Powered BaaS

Supabase makes a bold architectural bet: PostgreSQL is a better foundation for a modern BaaS than Firestore, MongoDB, or DynamoDB. The bet has paid off — Supabase's 76K GitHub stars and significant cloud ARR validate the approach.

The core insight is that PostgreSQL is already a complete platform: full ACID transactions, row-level security, stored procedures, triggers, extensions, full-text search, JSON support, and a rich ecosystem of tools. Supabase builds a developer-friendly layer on top rather than replacing the database.

# Supabase self-hosted (key services)
services:
  db:
    image: supabase/postgres:15.1.0.147
    environment:
      POSTGRES_PASSWORD: your-db-password
    volumes:
      - supabase_db:/var/lib/postgresql/data

  rest:
    image: postgrest/postgrest:v12.0.2
    environment:
      PGRST_DB_URI: postgres://authenticator:password@db:5432/postgres
      PGRST_JWT_SECRET: your-jwt-secret
      PGRST_DB_SCHEMAS: public,storage,extensions

  auth:
    image: supabase/gotrue:v2.140.0
    environment:
      GOTRUE_SITE_URL: https://app.yourdomain.com
      GOTRUE_JWT_SECRET: your-jwt-secret
      DATABASE_URL: postgres://supabase_auth_admin:password@db:5432/postgres
      GOTRUE_SMTP_HOST: smtp.yourdomain.com

  realtime:
    image: supabase/realtime:v2.27.5
    environment:
      DB_HOST: db
      DB_PASSWORD: your-db-password
      JWT_SECRET: your-jwt-secret

  storage:
    image: supabase/storage-api:v0.46.4
    environment:
      PGSQL_CONNECTION_STRING: postgres://supabase_storage_admin:password@db:5432/postgres

  studio:
    image: supabase/studio:20240101-8e4a94c
    ports:
      - "3000:3000"
    environment:
      SUPABASE_URL: http://kong:8000
      SUPABASE_ANON_KEY: your-anon-key

volumes:
  supabase_db:

Row-level security is Supabase's security model — define access rules at the database level using PostgreSQL policies:

-- Enable RLS on the table
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;

-- Users can only read their own posts and all published posts
CREATE POLICY "Read own or published posts"
ON posts FOR SELECT
USING (
  auth.uid() = user_id  -- Own posts
  OR published = true   -- Or any published post
);

-- Only the author can update their posts
CREATE POLICY "Authors can update own posts"
ON posts FOR UPDATE
USING (auth.uid() = user_id);

-- Check user role for admin access
CREATE POLICY "Admins can read everything"
ON posts FOR SELECT
USING (
  (SELECT role FROM user_profiles WHERE id = auth.uid()) = 'admin'
);

The Supabase JavaScript SDK is arguably the best-designed BaaS SDK available:

import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  'https://db.yourdomain.com',
  'your-anon-key'
);

// Type-safe queries (with TypeScript generated types)
const { data: posts, error } = await supabase
  .from('posts')
  .select(`
    id, title, content, created_at,
    author:users!inner(id, name, avatar_url),
    tags:post_tags(tag:tags(name))
  `)
  .eq('published', true)
  .order('created_at', { ascending: false })
  .limit(20);

// Real-time subscription (WebSocket)
const channel = supabase
  .channel('posts-changes')
  .on('postgres_changes', {
    event: 'INSERT',
    schema: 'public',
    table: 'posts',
    filter: 'published=eq.true',
  }, (payload) => {
    console.log('New post published:', payload.new);
  })
  .subscribe();

// File upload
const { data, error: uploadError } = await supabase.storage
  .from('avatars')
  .upload(`${userId}/avatar.png`, file, {
    contentType: 'image/png',
    upsert: true,
  });

Key features:

  • PostgreSQL with full SQL access
  • Auto-generated REST API (PostgREST) from your database schema
  • Row-level security (database-enforced access control)
  • Real-time via PostgreSQL logical replication
  • Auth: email/password, magic links, phone OTP, 50+ OAuth providers, SSO/SAML
  • File storage (S3-compatible)
  • Edge functions (Deno/TypeScript)
  • Vector search (pgvector)
  • Database branching for dev/staging
  • PostgreSQL extensions (PostGIS, pg_cron, pg_partman, TimescaleDB)
  • SDKs: JavaScript/TypeScript, Flutter, Swift, Kotlin, Python, C#, Go
  • Apache-2.0 license, 76K+ stars

Appwrite — The Multi-Runtime BaaS

Appwrite's architecture makes different tradeoffs: it abstracts the database behind a document API (no direct SQL), but provides far more flexibility in serverless function runtimes. If your team writes backend logic in Python, Ruby, or Swift — not just Node.js and TypeScript — Appwrite's 14 runtimes are a meaningful advantage.

# Appwrite Docker Compose (simplified)
services:
  appwrite:
    image: appwrite/appwrite:1.5.7
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    environment:
      - _APP_ENV=production
      - _APP_LOCALE=en
      - _APP_DOMAIN=api.yourdomain.com
      - _APP_DOMAIN_TARGET=api.yourdomain.com
      - _APP_DB_HOST=appwrite-mariadb
      - _APP_DB_PORT=3306
      - _APP_DB_SCHEMA=appwrite
      - _APP_DB_USER=appwrite
      - _APP_DB_PASS=password
      - _APP_REDIS_HOST=appwrite-redis
      - _APP_SMTP_HOST=smtp.yourdomain.com
      - _APP_SMTP_PORT=587
      - _APP_OPENSSL_KEY_V1=your-encryption-key
      - _APP_JWT_SECRET=your-jwt-secret
    depends_on:
      - appwrite-mariadb
      - appwrite-redis

  appwrite-worker-functions:
    image: appwrite/appwrite:1.5.7
    entrypoint: worker-functions

  appwrite-executor:
    image: openruntimes/executor:0.5.5
    # Executes serverless functions in Docker containers

  appwrite-mariadb:
    image: mariadb:10.11
    volumes:
      - appwrite_mariadb:/var/lib/mysql

  appwrite-redis:
    image: redis:7.2-alpine
    volumes:
      - appwrite_redis:/data

volumes:
  appwrite_mariadb:
  appwrite_redis:

The document model organizes data as collections of documents with typed attributes (string, integer, float, boolean, enum, array, relationship). This is similar to Firebase Firestore — flexible schema, no migrations required for adding fields.

import { Client, Databases, ID } from 'appwrite';

const client = new Client()
  .setEndpoint('https://api.yourdomain.com/v1')
  .setProject('your-project-id');

const databases = new Databases(client);

// Create a document
const post = await databases.createDocument(
  'main-db',     // Database ID
  'posts',       // Collection ID
  ID.unique(),   // Document ID
  {
    title: 'Hello from Appwrite',
    content: 'This is my post content.',
    published: true,
    authorId: currentUser.$id,
  }
);

// Query documents
const posts = await databases.listDocuments('main-db', 'posts', [
  Query.equal('published', true),
  Query.orderDesc('$createdAt'),
  Query.limit(20),
]);

Serverless functions run in isolated Docker containers with 14 available runtimes:

// Appwrite Function (Node.js runtime)
export default async ({ req, res, log, error }) => {
  const { userId } = JSON.parse(req.body);

  // Access other Appwrite services from inside a function
  const client = new Client()
    .setEndpoint(process.env.APPWRITE_ENDPOINT)
    .setProject(process.env.APPWRITE_PROJECT_ID)
    .setKey(process.env.APPWRITE_API_KEY);

  const databases = new Databases(client);
  const user = await databases.getDocument('users-db', 'profiles', userId);

  log(`Processing user: ${user.name}`);

  return res.json({ user, processed: true });
};

Available function runtimes: Node.js, Python, PHP, Ruby, Go, Swift, Dart, Bun, Deno, .NET, Kotlin, Java

Key features:

  • Document model (no direct SQL, flexible schema)
  • 14 function runtimes
  • Auth: email/password, OAuth2, phone/SMS, anonymous, JWT, magic links
  • 30+ OAuth providers
  • File storage with image transformation API
  • Real-time subscriptions (WebSocket)
  • Teams and permission management
  • Webhooks for all events
  • SDKs: 12+ platforms (Web, Flutter, Android, iOS, React Native, Node.js, Python, PHP, Ruby, Go, .NET, Swift)
  • Rate limiting and abuse protection
  • BSD-3-Clause license, 46K+ stars

Side-by-Side Comparison

FeatureSupabaseAppwrite
LicenseApache-2.0BSD-3-Clause
Stars76K+46K+
Database modelPostgreSQL (relational)Document (MariaDB backend)
Direct SQL✅ Full PostgreSQL
Row-level security✅ PostgreSQL RLSCollection-level permissions
Real-timePostgres logical replicationEvent-based WebSocket
Edge functionsDeno (TypeScript)14 runtimes
Vector search✅ pgvector
Database branching
SDK platformsJS, Flutter, Swift, Kotlin, Python12+ platforms including React Native
OAuth providers50+30+
Min RAM (self-hosted)2 GB4 GB
Number of services8+12+

Decision Framework

Choose Supabase if:

  • PostgreSQL's power is important — complex queries, JOINs, stored procedures, extensions
  • Row-level security (database-enforced access control) is a requirement
  • Vector search for AI/semantic features is on the roadmap
  • JavaScript/TypeScript is your primary development language
  • Database branching for dev/staging workflows is valuable
  • You want the largest BaaS community and ecosystem

Choose Appwrite if:

  • You need serverless functions in non-JavaScript languages (Python, Go, Ruby, PHP, Swift)
  • A document model (schemaless, no migrations) fits your mental model better than relational
  • You're building cross-platform apps with React Native or need the full SDK breadth
  • You want a more traditional BaaS experience similar to Firebase Firestore
  • BSD-3-Clause license is preferred over Apache-2.0

Cost Comparison

ScaleFirebase BlazeSupabase Self-HostedAppwrite Self-Hosted
1K MAU~$0$20–30/month$20–30/month
10K MAU~$50/month$20–30/month$30–40/month
100K MAU$200+/month$40–80/month$50–100/month

PostgreSQL as a Foundation: Why It Matters

Supabase's most distinctive architectural decision is using PostgreSQL directly rather than abstracting it behind a custom data layer. This deserves more examination than a simple "it uses Postgres" observation.

PostgreSQL is the most feature-complete open source relational database in existence. It handles ACID transactions, complex JOINs across dozens of tables, stored procedures, triggers, full-text search, JSON and JSONB document storage, geospatial data via PostGIS, time-series data via TimescaleDB, vector similarity search via pgvector, and an extension ecosystem covering hundreds of use cases. These are not hypothetical features — they are things that production applications need and use.

When Supabase gives you direct SQL access, it means you can use all of these capabilities without negotiating with an API layer. Need to run a complex analytics query across three tables with aggregates? Write the SQL. Need to implement a background job with pg_cron? Go ahead. Need to add vector search for semantic similarity? Enable the pgvector extension. The full power of one of the world's best databases is available without any API mediation.

Appwrite's document model makes a different tradeoff. By abstracting the database behind a document API, Appwrite provides a more consistent developer experience across different team compositions and makes the schema more flexible. Adding a new field to a collection does not require a migration. The tradeoff is that complex queries must be expressed in Appwrite's query API rather than SQL — which is generally fine for straightforward use cases but constraining for complex data access patterns.

Choosing Based on Your Application's Data Model

The right choice between Supabase and Appwrite often comes down to your application's data model and query patterns.

Applications with strong relational data — users who belong to organizations, organizations that have projects, projects that have tasks with assignees — benefit from Supabase's PostgreSQL foundation. These relationships are natural in SQL: foreign keys, JOINs, and cascading operations work exactly as you would expect. Row-level security policies let you express complex multi-tenant access rules (a user can read rows in the projects table where they have a membership, or where the project is public) at the database level, enforced before data leaves the database.

Applications with more document-like data — flexible metadata, user-generated content with variable structure, mobile app data with offline sync requirements — may find Appwrite's document model more natural. You can add new fields to documents without schema migrations, and the flexibility suits use cases where the data structure is not fully known in advance.

For applications that need heavy serverless function logic — data processing pipelines, webhook handlers, scheduled jobs — Appwrite's 14 function runtimes become a meaningful advantage. If your team has Python data engineers alongside JavaScript frontend developers, Appwrite's ability to run functions in both languages from the same platform is genuinely useful. Supabase's edge functions are TypeScript-only (Deno runtime), which covers most needs but leaves language diversity to other parts of the stack.

Both platforms run well in self-hosted configurations. The how-to-migrate-from-firebase-to-appwrite guide covers the Appwrite deployment and migration process in detail. For teams starting fresh and evaluating the full BaaS landscape including lighter-weight options, the comparison covers the spectrum from heavyweight (Supabase) to middleweight (Appwrite) to ultralight (PocketBase).

Self-Hosting Considerations

Both Supabase and Appwrite are designed to run self-hosted, but the operational experience differs.

Supabase's self-hosted deployment involves eight or more Docker containers: the PostgreSQL database, PostgREST API layer, GoTrue auth service, Realtime server, Storage API, Edge Functions runtime, Supavisor connection pooler, and Studio (the admin UI). These are all well-documented and the official docker-compose configuration works reliably, but it is a non-trivial number of services to manage. Minimum practical RAM for self-hosted Supabase is around 2 GB; 4 GB is more comfortable for a real application.

Appwrite's self-hosted deployment is similarly complex: the main application container, worker containers for different job types, the executor for running functions, MariaDB, Redis, and the InfluxDB and Telegraf containers for metrics. Appwrite requires more RAM at minimum (approximately 4 GB) but the Docker Compose configuration is also well-maintained.

Both platforms benefit from a reverse proxy layer (Caddy or Nginx) and a managed PostgreSQL/MariaDB backup strategy. For teams running these on a PaaS like Coolify or CapRover, both platforms deploy from Docker Compose, which makes management and backup straightforward.

Cost at scale is similar for both. A VPS with 4–8 GB RAM at $7–15/month handles a typical self-hosted BaaS deployment. At high usage levels, you may need to scale the database independently, but the fundamental economics — self-hosted infrastructure at predictable cost versus Firebase's per-operation pricing — hold regardless of which BaaS you choose. Database backup automation is critical for both: PostgreSQL dumps for Supabase and MariaDB dumps for Appwrite should run nightly to separate offsite storage, separate from the VPS where the application runs.


Related: Best Open Source BaaS Platforms 2026 · Appwrite vs PocketBase · PocketBase vs Supabase

See open source alternatives to Supabase on OSSAlt.

The SaaS-to-Self-Hosted Migration Guide (Free PDF)

Step-by-step: infrastructure setup, data migration, backups, and security for 15+ common SaaS replacements. Used by 300+ developers.

Join 300+ self-hosters. Unsubscribe in one click.