Backend as a Service vs Custom Backend (and Serverless)
Choose a backend as a service (BaaS) when your product's value is in the app, not in the plumbing: it gives you a database, auth, APIs, file storage and realtime on day one, so a small team ships in weeks instead of months. Build a custom backend when your core logic is complex, long-running or unusual enough that you would fight a platform's limits, or when you must control every layer. Serverless functions sit in between: they are a way to run your own code without managing servers, and they pair well with either. For most new products the best answer is a hybrid: a BaaS for the commodity parts and your own code for the parts that make you different.
#Three terms, clearly
- Backend as a service provides ready-made backend building blocks behind an SDK: a database with a generated API, user accounts and sessions, file storage, realtime updates, often functions and scheduled jobs. You configure rather than build.
- Custom backend is your own server application (Node, Go, Python, Java, Rails...) running on servers or containers you deploy, talking to a database you provision. You build everything, including auth, the API layer and the admin tools.
- Serverless is a hosting model, not a backend design: you deploy functions, the provider runs them on demand and bills per invocation or compute time. A custom backend can be serverless, and most BaaS platforms include serverless functions.
So "BaaS vs serverless" is a slightly mixed comparison. The real question is how much of the backend you build yourself, and serverless is one way to host the part you do build.
#Backend as a service vs custom backend vs serverless
| Backend as a service | Custom backend | Serverless functions only | |
|---|---|---|---|
| Time to first working version | Hours to days | Weeks | Days, plus a database and auth to add |
| Auth, sessions, password reset, OAuth | Included | You build or integrate | You integrate |
| API for your data | Generated from the schema | You write each endpoint | You write each function |
| Realtime | Usually included | You build (WebSockets, pub/sub) | Hard (functions are short-lived) |
| Long-running work | Limited by platform | Unlimited | Limited by timeouts |
| Control over every layer | Partial | Full | Partial |
| Ops burden | Low | High (servers, patching, scaling, backups) | Low for compute, separate for data |
| Cost at low usage | Free tier or a small plan | Servers plus your time | Very low |
| Cost at high usage | Plan plus usage rates | Hardware is cheap, people are not | Can grow fast per invocation |
| Lock-in | Depends on the platform's APIs and data access | Low (but you own all of it) | Depends on the provider's runtime |
#What "custom" really costs
The server is the cheap part of a custom backend. The expensive part is everything you rebuild that a BaaS already has, and then maintain forever:
- Auth: sign-up, e-mail verification, password reset, OAuth with several providers, MFA, session refresh, rate limiting on sign-in, account linking.
- An API layer: endpoints, validation, pagination, filtering, consistent errors, and authorization on every route.
- Authorization: who can read and change which rows. In a custom backend this is code in every handler; one missing check is a data leak.
- File uploads: signed URLs, size limits, access rules, image resizing.
- Realtime: WebSocket servers, fan-out, reconnection, presence.
- Background work: queues, retries, scheduled jobs, idempotency.
- Operations: backups and restore drills, migrations, monitoring, log retention, TLS, secrets, upgrades of every dependency.
None of this is hard individually. Together it is months of engineering before the first product feature, and a permanent maintenance load. That is the real cost to compare against a BaaS subscription.
#What a BaaS really costs
Be equally honest about the other side:
- Platform limits. Function timeouts, memory caps, request rates and database size are set by the plan. Know them before you design around them.
- Usage pricing. Most platforms bill above included amounts for database size, egress, monthly active users or function time. Model your expected usage at 10x today, not just today. See how to avoid surprise cloud bills.
- Lock-in. This is the big one, and it varies more than people think. A proprietary document database with its own query language is hard to leave. A platform built on plain Postgres, with a connection string you can use from any tool and a standard dump format, is much easier to leave.
- Opinionated design. You model data the way the platform expects. That is usually fine and sometimes a constraint.
#How to judge lock-in before you commit
Ask these five questions of any BaaS:
- Can I connect to the database directly with standard tools (psql, an ORM, a BI tool)?
- Can I export everything, including users with their password hashes, files and settings?
- Is the API based on open-source software I could run myself or find elsewhere?
- Is my authorization logic in the database (portable SQL policies) or in platform-specific rules?
- Can my own server code run next to the platform and use the same data?
The more "yes" answers, the less a BaaS choice locks you in.
#When to pick each
Pick a BaaS if:
- You are a small team or solo, and speed matters more than control.
- Your app is mostly CRUD on user-owned data, with auth, files and some realtime.
- You would rather pay a plan than run on-call for servers.
- You are validating a product and might change direction.
Pick a custom backend if:
- Your core logic is heavy computation, long-running processes or unusual protocols.
- You have strict requirements on infrastructure (specific cloud, on-premises, air-gapped).
- You have the team to build and run it, and the backend is itself a product differentiator.
Pick serverless functions as your main backend if:
- Your workload is spiky and event-driven (webhooks, scheduled tasks, light APIs).
- You already have a database and auth solution and only need glue code.
#The hybrid that most teams end up with
The common pattern is not either/or. It is a BaaS as the system of record, plus your own code where needed:
Clients (web, iOS, Android)
│ SDK: auth, data, files, realtime
▼
BaaS: Postgres + Auth + REST API + Storage + Realtime
▲ ▲
│ functions for glue │ direct Postgres connection
│ (webhooks, payments) │
Edge Functions Your own service (heavy jobs, ML, legacy integrations)Clients talk to the BaaS for everyday reads and writes, protected by row-level policies. Serverless functions handle webhooks and server-side secrets. And when you need something the platform's functions cannot do, such as a 30-minute data job or a Python ML model, you run your own service that connects to the same Postgres database. Nothing has to move.
#The hybrid on StitchDB
StitchDB is a BaaS built on Postgres: each project has its own database, Auth, an auto-generated REST and GraphQL API, Storage, Realtime and Edge Functions. Here is how each part of the hybrid looks.
Clients use the SDK. Supabase-style client code works by changing the URL and keys (compatibility):
import { createClient } from 'stitchdb-js'
const stitchdb = createClient('https://<project-ref>.p.stitchdb.com', '<anon key>')
const { data: todos } = await stitchdb.from('todos').select('*').eq('done', false)Row Level Security decides what each signed-in user can read and write, for the API, Realtime and Storage alike.
Glue code goes in Edge Functions. Deno functions deploy with stitchdb functions deploy <name>. Know the limits: as of November 2026, Free allows 60 seconds wall-clock per call and 128 MB memory, Pro 150 seconds and 150 MB, Scale and Enterprise 400 seconds and 256 MB, with 2 to 4 seconds of CPU time per request (functions limits). For longer work, background jobs run durable multi-step jobs with retries, or one long call of up to 60 minutes on Scale.
Your own service connects directly. Any server in any language uses the connection string from Settings → Database (TLS required), and Postgres tools such as Prisma, Drizzle, Flyway or Alembic work as with any Postgres (connect). For server-side API calls, the service_role key bypasses RLS, so keep it on servers only. You can also create a database role with exactly the rights a worker needs (schemas and roles).
Leaving stays possible. You can export a project (database, auth users, files, Edge Functions and settings) as one archive on every plan, and pg_dump works against the database. Because the APIs follow the open-source Postgres backend stack, the same client code can point elsewhere.
Honest trade-offs: StitchDB has no self-hosted edition documented, so "run it on my own hardware" is not an option in the usual sense (approved accounts can attach their own servers for hosting, but StitchDB still operates them). Its data centers are in the EU only. And as with any BaaS, plan limits apply; check pricing against your expected usage.
For a broader look at platforms, see the best backend as a service platforms, and for the cost view, the BaaS pricing comparison.
#FAQ
#Is a backend as a service cheaper than a custom backend?
Almost always at the start, because you are not paying engineers to rebuild auth, APIs and storage. At very large scale, raw infrastructure can be cheaper than a platform's usage rates, but the engineering and on-call cost of a custom stack often outweighs that.
#Is serverless the same as a backend as a service?
No. Serverless is a way to run your own code without managing servers. A BaaS provides ready-made backend services, and many include serverless functions for your custom logic.
#Can I start with a BaaS and move to a custom backend later?
Yes, especially if the BaaS uses a standard database. Move pieces gradually: keep the data in Postgres and replace or add services one at a time.
#What are the biggest risks of a BaaS?
Platform limits you hit later, usage costs you did not model, and lock-in through proprietary data models or APIs. Check limits, export options and direct database access before committing.
#Do I still need backend developers with a BaaS?
You need someone who understands data modeling, security policies and server-side logic. You need far fewer people to run infrastructure.
Get the commodity parts done today: create a free project and connect your app with the SDK.