Backend as a service (BaaS)
Hosted sign-in, database, file storage and realtime updates that a web or mobile app calls straight from the client through an SDK, with access rules enforced on the provider’s side instead of in an API server you write.
2 technologies on this page ↓How it works
With a PaaS you still write the backend: an API server that checks who the user is and decides what they may read. A BaaS removes that server for the common cases. Each project gets one endpoint and a public key that ships inside the app; Supabase says this publishable key is “safe to expose online” because it “only reaches what Row Level Security allows”. A user signs in through the BaaS’s auth service, which issues a JWT, and the SDK attaches that token to every later call. The data API reads the token and applies rules you wrote, on every request, on the provider’s servers. In Firebase these are Security Rules, such as allow read, write: if request.auth != null && request.auth.uid == userId. In Supabase they are Postgres row-level security policies, which Supabase describes as “adding a WHERE clause to every query”: with the policy (select auth.uid()) = user_id, a plain select * from todos returns only the caller’s rows. Supabase’s stack shows the usual parts: GoTrue issues JWTs, PostgREST turns the database into a REST API, Realtime streams database changes over WebSockets, the Storage API keeps files in S3-compatible storage with their metadata in Postgres, and Deno runs edge functions, all behind one gateway. Work that must not run in a user’s browser, such as charging a card, goes into a server-side function that holds a secret key; that key bypasses the rules, so it never ships in the client. You pay per use: Firebase’s no-cost Spark plan covers 50,000 Firestore document reads and 20,000 writes a day and 50,000 monthly active users for Authentication, and usage beyond that is billed at Google Cloud rates.
A hotel’s key-card system instead of hiring a guard for every corridor. The front desk checks who you are once and hands you a card (the token). After that, every door reads the card and decides for itself whether it opens (the rules). You never staff the corridors, but the locks are only as good as their programming: set one door to “any card” and every guest can walk in.
Reach for it when
- A web or mobile app whose backend is mostly sign-in, reading and writing the user’s own records, file uploads and live updates
- A small team or a prototype that would rather not build, deploy and scale an API server for create, read, update and delete
- Screens that must update live, such as chat, presence or collaborative lists, where the BaaS already pushes changes over WebSockets
- You want the database itself to enforce access, so that a bug in one client can’t read another user’s rows
Think twice when
- Nobody will write and test the access rules: in Supabase, a table in an exposed schema without row-level security “is readable and writable by any role with a grant on it”
- Most of the logic is business rules that must not be bypassed, such as payments or multi-step workflows: anything in the client can be changed by the user, so that code belongs in server-side functions or your own API
- You can’t afford to rewrite the client if the vendor goes away: when Parse shut down, every app had a year to move its data and switch to self-hosted Parse Server or another platform
- Screens that read thousands of records per visit: per-operation pricing, such as Firestore’s charge per document read beyond the free 50,000 a day, grows with every user who opens them
A real example
A to-do app on Supabase stores tasks in a todos table with a user_id column. The team turns on row-level security and adds two policies: one lets signed-in users select rows where (select auth.uid()) = user_id, the other uses with check so an insert can’t create a row that belongs to someone else. The browser app ships with the project URL and the publishable key, signs users in through Supabase Auth, and queries the table through the generated REST API; each user sees only their own tasks, although the query has no filter. A shared list subscribes to changes through Realtime, so a task added on a phone appears on the laptop. A nightly function that emails reminders runs server-side with the secret key, which bypasses row-level security to read every user’s tasks. The team wrote no API server; what it owns is the schema, the policies and the tests that prove them.
Technologies
Specific products, and what each does differently.
What each provider calls it
- AWS
- AWS Amplify: define auth, data, storage and functions in TypeScript. Amplify Auth is powered by Amazon Cognito; Amplify Data deploys a real-time API on AWS AppSync backed by Amazon DynamoDB and secured by authorization rules
- Google Cloud
- Firebase: Authentication; Cloud Firestore and Realtime Database guarded by Firebase Security Rules; Cloud Storage for Firebase; Cloud Functions for Firebase; Data Connect for PostgreSQL on Cloud SQL with type-safe SDKs
- Azure
- No current all-in-one BaaS: Azure Mobile Apps is retired (the Community Toolkit Datasync library replaces it for .NET 8 and later), and Static Web Apps database connections ended on November 30, 2025. The nearest parts are Data API builder, a free open-source engine that serves REST and GraphQL over SQL Server, Azure SQL, Cosmos DB, PostgreSQL and MySQL, and managed Azure Functions
- Open source & others
- Supabase (Apache 2.0): Postgres with GoTrue auth, PostgREST, Realtime, Storage and Deno edge functions; Appwrite (BSD-3-Clause); PocketBase (MIT); Parse Server (Apache 2.0), open-sourced when Parse’s hosted service closed
Where BaaS sits#
BaaS is not in NIST’s three service models. It sits beside PaaS and functions: instead of running your backend code, it replaces the common parts of a backend with ready-made services.
| Model | You write | The client talks to | Access control lives in |
|---|---|---|---|
| Platform as a service | An API server and its business logic | Your API | Your server code |
| Functions as a service | One handler per event or route | Your functions, usually behind an API gateway | Your function code |
| Backend as a service | The schema, the access rules and a few functions | The provider’s auth, data, storage and realtime APIs, directly | Rules on the provider’s side: Security Rules or row-level security |
- Most BaaS products include functions for the logic that doesn’t fit rules, so in practice an app mixes the bottom two rows. Serverless architecture is the name for building a whole app this way.
The usual building blocks#
Providers bundle different sets, but most offer these, each reachable from client SDKs for the web, iOS, Android and Flutter.
Authentication
whoSign-up, sign-in, password reset and OAuth sign-in with other providers. It issues the token that every other service reads.
Database API
whatSQL or NoSQL storage reached through the SDK, REST or GraphQL, with per-user rules applied to every query: Firestore and Security Rules, Postgres and row-level security, DynamoDB behind AppSync.
File storage
blobsUploads and downloads of images, media and other binary files, guarded by the same kind of rules as the database.
Realtime
pushClients subscribe over WebSockets and receive changes as they happen, for chat, presence and shared lists.
Functions
escape hatchServer-side code triggered by HTTP requests, database events or schedules, for logic that must not run in the client. It can hold the secret key that bypasses the rules.
Push and messaging
reachSome providers, such as Firebase and AWS Amplify, also send push notifications and emails to users.
Two keys, and why the public one is safe#
A BaaS hands out two kinds of credentials. The public one goes into the app bundle, where anyone can read it; on its own it only reaches what the rules allow for an anonymous visitor. The secret one bypasses the rules entirely and belongs only in servers, functions and scheduled jobs. Supabase puts it as a building: the publishable key is taped to the front door and opens the lobby, while the secret key is the master key that stays in your pocket.
Supabase is replacing its older long-lived JWT keys, anon and service_role, with short sb_publishable_ and sb_secret_ keys, and is deprecating the old ones by the end of 2026. Both systems work side by side until the legacy keys are disabled in the dashboard. The safety of the public key still depends on the rules: Supabase notes that a new table can start with every privilege granted to the anon and authenticated roles, and adding policies doesn’t take those grants back.
In code · sql
-- The access rules live in the database, not in an API server
alter table todos enable row level security;
create policy "Individuals can view their own todos."
on todos for select
to authenticated
using ( (select auth.uid()) = user_id );
create policy "Individuals can create their own todos."
on todos for insert
to authenticated
with check ( (select auth.uid()) = user_id );
-- A client running `select * from todos` now gets only its own rows:
-- the policy is added to the query as `where auth.uid() = todos.user_id`Often confused with
Where it came from2011–2020
Around 2011, every mobile app needed the same backend: user accounts, push notifications, links to social networks and cloud storage, each with its own API to wire up. A wave of startups, most founded in 2011 or later, sold these as one “mobile backend as a service” with an SDK. Parse, founded in 2011 by Tikhon Bernstam, Ilya Sukhar, James Yu and Kevin Lacker, let mobile developers store data in the cloud, manage log-ins, send push notifications and, from September 2012, run custom code on the back end; by 2012 about 20,000 developers used it. Firebase let apps listen to changes in its database over WebSockets.
The big platforms bought in. Facebook acquired Parse in 2013, and on October 21, 2014, Firebase announced it had joined Google, by then used by 110,000 developers, promising to stay platform agnostic with clients for iOS, Android and the web. Then the risk showed. On January 28, 2016, Parse announced it would wind down, fully retiring on January 28, 2017. It released a tool to move each app’s data to any MongoDB database and the open-source Parse Server, which runs most of the Parse API on your own Node.js server so apps could keep their client code.
The next generation leaned on open source and SQL. Paul Copplestone had hit scaling problems with Firebase, moved that part of a system to Postgres and rebuilt Firebase’s change stream on top of it as open source. When it gained traction, Copplestone and Anthony Wilson turned it into a company. Supabase launched in alpha in June 2020 and in beta that December, built on Postgres “rather than a NoSQL store” and on existing open-source tools, with the test “Can a user run this product with nothing but a Postgres database?” Firebase itself now offers Data Connect on PostgreSQL, and AWS Amplify defines the backend in TypeScript.
Why it’s built this way
- Let the client call the database directly, guarded by rules on the server
- Without an API server in the middle, the rules are the only gate. Firebase Security Rules “stand between your data and malicious users”, and Supabase calls row-level security “defense in depth” because it also protects data reached through other tools.
- One SDK in front of many services
- Each backend feature had its own API that had to be wired into every app. BaaS providers bridged the frontend and those services with a unified API and SDK, so developers didn’t rebuild the same backend for each app.
- Realtime by default
- Copplestone singled out Firebase’s system for listening to database changes over WebSockets as what was missing in Postgres, and rebuilt it first. Live sync is what lets a client keep its view current without polling.
- Postgres and open source instead of a proprietary store
- After Parse, lock-in was a known risk. Supabase says it makes it easy to migrate in and out, keeps its cloud compatible with the self-hosted product, and uses standards such as pg_dump and CSV files for portability.
Timeline
- 2011
Parse is founded; mobile backend as a service startups multiply
- 2013
Facebook acquires Parse
- 2014
Firebase joins Google on October 21, with 110,000 developers
- 2016
Parse announces its shutdown on January 28 and open-sources Parse Server
- 2017
Parse’s hosted service is retired in January
- 2020
Supabase launches in alpha in June and beta in December
- Wikipedia: Backend as a service (features, MBaaS, startups from 2011)
- Wikipedia: Parse, Inc. (founders, 2011; Facebook 2013; shutdown January 2017)
- Parse blog: Moving On, by Kevin Lacker (Jan 28, 2016) · archived copy, original
- Firebase blog: Firebase is Joining Google, by James Tamplin (Oct 21, 2014)
- The New Stack: Supabase Takes Aim at Firebase with a Scalable Postgres Service (Jan 4, 2022)
- Supabase docs: Architecture (Postgres rather than NoSQL, product principles)
- Firebase docs: Firebase Security Rules
Sources20
- Wikipedia: Backend as a service (common features, client SDKs, pricing models)
- Supabase docs: Architecture (GoTrue, PostgREST, Realtime, Storage, Deno, Envoy)
- Supabase docs: Row Level Security (policies as WHERE clauses, grants, anon and authenticated roles)
- Supabase docs: Understanding API keys (publishable and secret keys, legacy key deprecation)
- Firebase docs: Firebase Security Rules
- Firebase docs: Basic Security Rules (content-owner only access)
- Firebase: Pricing (Spark and Blaze plans, Firestore and Authentication no-cost limits)
- Firebase docs: Firebase Data Connect (PostgreSQL on Cloud SQL)
- AWS Amplify docs: How Amplify works
- AWS Amplify docs: Set up Amplify Data (AppSync and DynamoDB)
- AWS Amplify docs: Set up Amplify Auth (Amazon Cognito)
- Microsoft Learn: Azure Mobile Apps overview (retired)
- Microsoft Learn: Connecting to a database with Azure Static Web Apps (retirement on Nov 30, 2025)
- Microsoft Learn: What is Data API builder?
- Microsoft Learn: What is Azure Static Web Apps? (managed Azure Functions APIs)
- Community Toolkit: Datasync
- supabase/supabase on GitHub (Apache 2.0)
- appwrite/appwrite on GitHub (BSD-3-Clause)
- pocketbase/pocketbase on GitHub (MIT)
- parse-community/parse-server on GitHub (Apache 2.0)