PocketBase
Open Source backend for your next SaaS and Mobile app in 1 file.
Introduction
PocketBase is the darling of the modern “Indie Hacker” movement. It is an open-source Backend-as-a-Service (BaaS) that compresses the complexity of a modern cloud stack (Database, API, Auth, Storage) into a single 15MB executable file.
Written in Go, PocketBase challenges the assumption that you need Docker containers, microservices, and complex orchestration to build a scalable app. By leveraging embedded SQLite in high-performance WAL mode, it offers a solution that is incredibly easy to deploy yet surprisingly performant.
Architecture and Technology
The “One File” architecture is not a gimmick; it is a fundamental design choice.
Core Components
- Embedded SQLite (WAL Mode):
- PocketBase uses SQLite, the most deployed database engine in the world.
- It runs in Write-Ahead Logging (WAL) mode, which allows for concurrent readers and vastly improved write performance compared to traditional SQLite locking.
- Because the database is just a file (
pb_data/data.db), backups are trivial: standard file copy tools or S3 sync scripts work perfectly.
- Go Runtime: The entire application is a self-contained Go binary. This means it has zero dependencies. No
npm install, no python venv. - Realtime Engine: Using Server-Sent Events (SSE), PocketBase pushes database changes to subscribed clients instantly. This acts as a simpler, more firewall-friendly alternative to WebSockets.
The “Framework” Capability
PocketBase is unique because it can be used in two ways:
- As a Standalone Binary: You download it, run
./pocketbase serve, and manage everything via the UI. - As a Go Framework: You can import PocketBase as a library into your own Go code. This allows you to “intercept” core behaviors using hooks.
Example: Intercepting a Record Creation (Go)
package main
import (
"log"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/core"
)
func main() {
app := pocketbase.New()
app.OnRecordBeforeCreateRequest("posts").Add(func(e *core.RecordCreateEvent) error {
// Automatically set the author to the current logged-in user
user := e.HttpContext.Get("authRecord")
if user != nil {
e.Record.Set("author", user.Id)
}
return nil
})
if err := app.Start(); err != nil {
log.Fatal(err)
}
}
Developer Experience (DX)
PocketBase optimizes for “Flow State.” The Admin UI is fast, clean, and intuitive.
Data Modeling
You create functionality by creating “Collections” (Tables).
- Base Collection: Standard CRUD items (Articles, Products).
- Auth Collection: Users with email/password or OAuth (Google, GitHub) enabled.
- View Collection: Read-only SQL views for complex reporting.
SDKs
Official SDKs exist for JavaScript/TypeScript and Dart (Flutter).
- Auto-Typed: The community provides tools to generate TypeScript types directly from your SQLite schema.
const record = await pb.collection('posts').create({ title: 'Hello World', content: 'This is a post', author: pb.authStore.model.id, });
Authentication
Auth is usually the hardest part of a new app. PocketBase solves it.
- It handles JWT generation, refresh tokens, and password reset emails.
- OAuth2: enabling “Login with Google” is literally pasting a Client ID and Secret into the dashboard.
Deployment and Scaling
Vertical Scaling Only
PocketBase is designed to scale vertically. You cannot run 5 instances of PocketBase behind a load balancer pointing to the same SQLite file (unless using advanced replication tools like LiteFS, which is experimental).
- Is this a problem? For 99% of apps: No. A single $20 VPS with fast NVMe storage can handle 10,000+ concurrent real-time connections and millions of requests per day.
- The Limit: If you are building the next Uber or Twitter, you will eventually outgrow a single write-master SQLite setup. But you will likely have funding to migrate by then.
Hosting
- Fly.io / Railway / DigitalOcean: Deployment is trivial. Since it handles its own database, you just mount a persistent volume for the
pb_datafolder. - Coolify: A popular self-hosted PaaS that has a one-click template for PocketBase.
Typical Use Cases
1. Mobile Apps (Flutter/React Native)
PocketBase provides exactly what mobile apps need: Auth, Data, File Uploads, and Realtime sync. The Dart SDK is first-class.
2. SaaS MVPs
Speed is life for startups. PocketBase lets you build the backend in an afternoon.
- Scenario: A “Micro-SaaS” for uptime monitoring. The cron jobs can be written in Go inside the same binary, and the UI fetches status logs via the API.
3. Internal Business Apps
Replacing spreadsheets.
- Scenario: An inventory tracker for a warehouse. The Admin UI is good enough for warehouse staff to use directly for data entry.
Strengths
- Portability: “Data Sovereignty” in a file. You can zip your entire backend and move it to a laptop, a Raspberry Pi, or a massive server in seconds.
- Simplicity: It removes “Decision Fatigue.” You don’t choose a cache (Redis), a DB (Postgres), or an Auth provider (Auth0). You just use PocketBase.
- Performance: The latency between “Application Logic” and “Database” is effectively zero (same memory space). This makes it faster than traditional APIs for many read-heavy operations.
Limitations and Trade-offs
- No Transactions (via API): The default HTTP API doesn’t support complex multi-table transactions (e.g., “Create Order AND Decrement Inventory OR Fail Both”). You must write custom Go code or use hooks to ensure data integrity in complex scenarios.
- SQLite Limits: While powerful, SQLite lacks some advanced features of PostgreSQL (like Geo-spatial queries or advanced JSON indexing).
- Bus Factor: The project is largely driven by a single brilliant creator (Gani Georgiev). While open source, the development velocity is tied to a small team.
Verdict
PocketBase is the ultimate tool for the “Full Stack 2.0” era. It proves that complexity is optional. If you are building a new product, a side project, or a medium-scale application, PocketBase offers the fastest path from “Idea” to “Deployed” of any tool in the market today. It brings back the joy of programming by letting you ship.