← All articles
The year 2026 displayed on black cubes

PocketBase: Self-Hosted Backend in a Single File

Development 2026-03-04 · 3 min read pocketbase backend firebase alternative self-hosted sqlite realtime auth
By Selfhosted Guides Editorial TeamSelf-hosting practitioners covering open source software, home lab infrastructure, and data sovereignty.

PocketBase packs a complete backend — SQLite database, real-time subscriptions, authentication, file storage, and an admin UI — into a single executable file. It's the shortest path from "I need a backend" to something actually running.

Photo by BoliviaInteligente on Unsplash

If you've used Firebase or Supabase but want to self-host without the complexity, PocketBase is worth a close look.

What PocketBase Gives You

A single pocketbase binary provides:

The admin dashboard is built in and available immediately after starting.

Getting Started

Download the appropriate binary from GitHub releases:

# Linux AMD64
curl -L https://github.com/pocketbase/pocketbase/releases/latest/download/pocketbase_linux_amd64.zip -o pocketbase.zip
unzip pocketbase.zip
chmod +x pocketbase

# Start the server
./pocketbase serve

Navigate to http://localhost:8090/_/ to access the admin UI and create your first admin account.

Docker Setup

For a persistent deployment with Docker:

services:
  pocketbase:
    image: ghcr.io/muchobien/pocketbase:latest
    container_name: pocketbase
    ports:
      - "8090:8090"
    volumes:
      - pb_data:/pb/pb_data
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8090/api/health"]
      interval: 10s
      timeout: 5s
      retries: 3

volumes:
  pb_data:

Creating Your Data Model

In the admin UI under Collections, create collections (think: database tables):

  1. Click New collection
  2. Name it (e.g., posts)
  3. Add fields: text, number, email, date, select, file, relation, etc.
  4. Set API rules to control who can read/write

PocketBase generates the full REST API immediately — no code needed.

Example: Blog Posts Collection

Field Type Required
title Text
content Editor
published Bool
author Relation (users)
cover File

This collection automatically gets:

Authentication

PocketBase has a built-in _pb_users_auth_ collection. To authenticate:

import PocketBase from 'pocketbase';

const pb = new PocketBase('http://localhost:8090');

// Login
const authData = await pb.collection('users').authWithPassword(
  '[email protected]',
  'password123'
);

// The client automatically stores the token and refreshes it
console.log(pb.authStore.isValid); // true
console.log(pb.authStore.model);   // user record

OAuth2 works similarly — just add providers (Google, GitHub, Discord, etc.) in the admin UI and call authWithOAuth2().

Real-Time Subscriptions

This is where PocketBase stands out from simple REST APIs:

// Subscribe to all changes in the 'posts' collection
pb.collection('posts').subscribe('*', function(e) {
  console.log(e.action); // create, update, delete
  console.log(e.record); // the changed record
});

// Subscribe to a single record
pb.collection('posts').subscribe('RECORD_ID', function(e) {
  console.log('Post updated:', e.record.title);
});

// Unsubscribe
pb.collection('posts').unsubscribe();

This works without WebSockets — PocketBase uses Server-Sent Events under the hood.

Extending with JavaScript Hooks

PocketBase has a JavaScript runtime (based on goja) for server-side logic:

// pb_hooks/main.pb.js

// Run before creating a post
onRecordBeforeCreateRequest((e) => {
  const record = e.record;

  // Validate slug uniqueness
  if (!record.get("slug")) {
    const title = record.get("title");
    record.set("slug", title.toLowerCase().replace(/\s+/g, "-"));
  }

  return e.next();
}, "posts");

// Custom API endpoint
routerAdd("GET", "/api/stats", (c) => {
  const count = $app.dao().findRecordsByFilter("posts", "published = true", "", 0, 0).length;
  return c.json(200, { published: count });
});

Hooks support onRecordBefore/AfterCreate/Update/Delete, mail hooks, and more.

File Storage

By default, files are stored locally in pb_data/storage. For S3:

In the admin UI → Settings → Files storage, configure:

Or pass at startup:

./pocketbase serve \
  --s3Endpoint=https://s3.amazonaws.com \
  --s3Region=us-east-1 \
  --s3Bucket=my-pb-files \
  --s3AccessKey=AKIAIOSFODNN7EXAMPLE \
  --s3Secret=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

API Rules

Control access with rule strings. They use a filter syntax:

Rule Meaning
"" (empty) Locked — no one can access
@request.auth.id != "" Any authenticated user
@request.auth.id = author Only the record's author
admin = @request.auth.id Custom admin field check

Set these per collection and per operation (list, view, create, update, delete).

Comparison: PocketBase vs Alternatives

Feature PocketBase Supabase Appwrite Firebase
Self-hostable
Deployment complexity Single binary Docker Compose (many containers) Docker Compose Managed
Database SQLite PostgreSQL MariaDB NoSQL
Real-time SSE WebSockets WebSockets WebSockets
Free tier Unlimited (self-hosted) Generous Generous Limited

PocketBase's single-binary deployment is its killer feature. Supabase is more powerful for complex SQL needs; PocketBase wins for simple, fast deployments.

Production Considerations

Backups: SQLite databases are easy to back up — just copy pb_data/data.db:

# Daily backup cron
0 2 * * * sqlite3 /path/to/pb_data/data.db ".backup '/backups/pocketbase-$(date +%Y%m%d).db'"

Performance: SQLite handles thousands of requests per second for most apps. For write-heavy workloads with concurrent writers, consider whether PostgreSQL (via Supabase or Directus) is more appropriate.

Scaling: PocketBase is single-instance. If you need horizontal scaling, it's not the right tool. For most projects, vertical scaling (a bigger VM) gets you very far.

When to Use PocketBase

PocketBase is excellent for:

Skip it for: multi-region deployments, write-heavy apps expecting PostgreSQL semantics, or anywhere you need high-availability replication.

Get free weekly tips in your inbox. Subscribe to Self-Hosted Weekly