PocketBase Review: A Backend, Database, and Auth in One Go Binary
A measured look at PocketBase, the Go-based backend that bundles SQLite, a REST API, realtime, auth, and an admin dashboard into a single executable you run with one command.
Most backend stacks ask you to wire together at least three moving parts before you write a line of product code: a database, an API layer, and an auth service. PocketBase collapses those three into a single executable. You download one file, run ./pocketbase serve, and you have a working API, a SQLite database, user authentication, file storage, and an admin dashboard listening on 127.0.0.1:8090. No Docker, no separate Postgres process, no managed cloud account.
We ran PocketBase locally and on a small VPS to see how much of that promise holds up, and where the single-binary model starts to cost you.
What actually ships inside the binary
The download is one compiled Go program. Everything below runs in that same process:
- An embedded SQLite database. PocketBase runs SQLite in WAL (write-ahead logging) mode, so reads don’t block writes. Your data lives in a
pb_data/directory next to the binary. - An auto-generated REST API. You define collections (the PocketBase term for tables) in the dashboard, and the API for list, view, create, update, and delete is generated for you, including filtering, sorting, and pagination.
- Realtime subscriptions. Clients subscribe to collection changes over Server-Sent Events (SSE). When a record changes, subscribed clients get the update without polling.
- Built-in auth. Email/password, OAuth2 providers (Google, GitHub, and others), and one-time-password flows are included, along with email verification and password reset.
- File storage. Uploads go to the local disk by default, or to any S3-compatible bucket if you flip a setting.
- An admin dashboard at
/_/for managing collections, records, settings, and backups in the browser.
There are official JavaScript and Dart SDKs, so a web SPA or a Flutter app can talk to it without you hand-rolling fetch wrappers. The access-control model is per-collection rule expressions: each operation (list, view, create, update, delete) gets a filter string like @request.auth.id = user.id, evaluated per request. That keeps authorization next to the data instead of scattered across middleware.
Where PocketBase fits, and the limits to respect
The single-binary design is genuinely pleasant for prototypes, internal tools, side projects, and the backend for a mobile or single-page app. You can scp the binary and the data directory to a server and be live in minutes. There is no connection pool to tune and no second service to monitor.
The trade-off is structural and worth being honest about. SQLite is a single-file, single-writer database. PocketBase scales vertically (a bigger box) rather than horizontally (more boxes). There is no built-in clustering or multi-node replication. For read-heavy workloads you can go a surprisingly long way on one machine, because WAL mode and in-process queries are fast and there’s no network hop to a database server. But if your plan depends on running several stateless API nodes behind a load balancer sharing one database, that is not the shape PocketBase is built for.
The second limit is maturity. PocketBase has spent its life in the 0.x range and its author has been clear that breaking changes can land before a 1.0. That is fine for a project where you control the deploy and read the changelog; it is a real consideration if you need long-term API stability guarantees.
| Dimension | PocketBase | Supabase | Firebase |
|---|---|---|---|
| Database | SQLite (embedded) | Postgres | Firestore |
| Hosting | Self-host one binary | Managed or self-host | Managed only |
| Realtime transport | Server-Sent Events | WebSockets | WebSockets |
| Scaling model | Vertical, single node | Horizontal | Managed/auto |
| License | MIT (open source) | Apache 2.0 core | Proprietary |
Extending it without standing up a second service
The part that separates PocketBase from a generic backend-as-a-service is that it is a framework, not just a server. You have two ways to add custom logic.
The lighter path is JavaScript hooks. Drop files into a pb_hooks/ directory and PocketBase runs them on an embedded JS engine. You can react to events like onRecordAfterCreateRequest, register custom routes, run scheduled jobs, and call out to other services, all without recompiling anything. This is the fastest way to add a webhook handler or a derived field.
The heavier path is using PocketBase as a Go framework. You import it as a Go module, register your own hooks and routes in main.go, and compile your own binary. You get the full type system and the standard library, and you ship a single custom executable that still contains the database and dashboard. This is the route to take when your business logic is substantial enough that you want a compiler checking it.
Either way you are writing code, and the editor you write it in matters more than the framework. If you are extending PocketBase in Go or in pb_hooks JavaScript, an AI-aware editor that understands the surrounding code pays for itself quickly on a codebase whose conventions you are still learning.
Cursor
An AI-native code editor that's a strong fit for writing PocketBase Go extensions or pb_hooks JavaScript, with inline completion and codebase-aware chat for an unfamiliar framework.
Free tier; Pro at $20/mo
Affiliate link · We earn a commission at no cost to you.
For a small team, the developer-experience math is straightforward: one binary to deploy, one directory to back up, one process to restart, and your custom logic compiled in or hot-loaded from a hooks folder. That is a meaningfully smaller surface than a database server, an API container, and an auth provider maintained separately.
FAQ
Is PocketBase production-ready?+
Can PocketBase scale?+
Do I need to know Go to use it?+
PocketBase is not trying to be every backend. It is trying to be the one you reach for when the cost of assembling a stack is higher than the cost of a vertical scaling ceiling you may never hit. For prototypes, internal tools, and the long tail of apps that comfortably live on one server, that trade is easy to take.
Related tools
Beehiiv
Newsletter platform with built-in ad network and Boost referrals.
Try Beehiiv →
Webflow
Visual site builder with real CSS export and a CMS that scales.
Try Webflow →
Some links above are affiliate links. We may earn a commission if you sign up. See our disclosure for details.
Related reading
2026-06-10
Typesense vs Meilisearch in 2026: Self-Hosted Search Compared
A measured comparison of Typesense and Meilisearch for self-hosted search in 2026 — memory model, licensing, features, and which one fits your stack.
2026-06-10
LiteFS and Distributed SQLite: How Cross-Region Replication Actually Works
A practical look at LiteFS, the FUSE-based filesystem that replicates SQLite across regions: how transaction shipping works, the single-writer tax, and when to reach for it over rqlite or libSQL.
2026-06-09
Caddy vs Nginx in 2026: Which Reverse Proxy Should You Run?
A measured comparison of Caddy and Nginx for 2026 — automatic HTTPS, config ergonomics, HTTP/3, performance under load, and which one fits your stack.
2026-06-09
Convex vs Supabase in 2026: Reactive Backend or Postgres BaaS?
A measured comparison of Convex and Supabase for developers in 2026 — reactivity by default versus a Postgres database you own, plus lock-in, cost, and which fits your app.
2026-06-08
Neon vs Supabase in 2026: Which Serverless Postgres Should You Pick?
Neon and Supabase both give you Postgres without managing a server, but they solve different problems. We break down branching, scale-to-zero, auth, and pricing to help you choose.
Get the best tools, weekly
One email every Friday. No spam, unsubscribe anytime.