LOCAL-FIRST SQLITE · WEB, MOBILE & DESKTOP

Familiar, local SQLite.
Shared across devices.

Build responsive apps with the SQLite you already know.
Keep them in sync through a bucket. No sync servers to manage.

Ship faster. Keep costs low.

Try it. Place an order on the phone.

POTLUCK CAFÉ · OVERVIEW

A good day, together.

Sales today$7.00
Orders21 ready
ON THE SHELF Restock +5
Coffee11
Croissant7
Latest order#102 · CroissantPreparing
Up to date
The overviewDesktop · sales & stock
POTLUCK CAFÉ · PREPARE

Made with care.

1 to prepare
#102Croissant
1 order ready
Up to date
The preparation boardTablet · orders & updates
POTLUCK CAFÉ · ORDER

Something good.

Total$4.00

11 available

Your next order starts here.

Up to date
The counterPhone · place an order

One café. Three views of the same shared data.

Interactive illustration · sample orders · sync timing simplified

Your stack. Your storage. A full-featured 30-day trial.

BUILD ON WHAT YOU KNOW

Build cross-platform apps.
In Days.

Use familiar SQLite and ready-made SDKs across web, mobile and desktop. Spend less time learning a backend and building integrations—and more time building your app.

Same familiar SQLite.Tables. Queries. Transactions.
SELECT title FROM notes;

Pick your stack. Bring your SQL.

Swipe to compare platforms

SDK and language support by platform
Your stack↓   Your platform →BrowserWebAssemblyiOS& iPadOSAndroid macOS Windows LinuxglibcLinuxmusl
JavaScript · TypeScriptSupportedSupportedSupportedSupportedSupportedSupportedSupported
PythonNot listedNot listedNot listedSupportedSupportedSupportedSupported
Java · KotlinNot listedNot listedSupportedSupportedSupportedSupportedNot listed
Swift · Objective-CNot listedSupportedNot listedSupportedNot listedNot listedNot listed
Dart · FlutterNot listedSupportedSupportedSupportedSupportedSupportedNot listed
GoNot listedNot listedNot listedSupportedSupportedSupportedNot listed
RustNot listedNot listedNot listedSupportedSupportedSupportedSupported
C# · .NETNot listedSupportedSupportedSupportedSupportedSupportedSupported
C · C++Not listedSupportedSupportedSupportedSupportedSupportedSupported
App framework support by platform
Your stack↓   Your platform →BrowserWebAssemblyiOS& iPadOSAndroid macOS Windows LinuxglibcLinuxmusl
ElectronNot listedNot listedNot listedSupportedSupportedSupportedNot listed
TauriNot listedNot listedNot listedSupportedSupportedSupportedNot listed
QtNot listedNot listedNot listedSupportedSupportedSupportedNot listed
FlutterNot listedSupportedSupportedSupportedSupportedSupportedNot listed
React NativeNot listedSupportedSupportedNot listedNot listedNot listedNot listed
Capacitor · IonicNot listedSupportedSupportedNot listedNot listedNot listedNot listed
.NET MAUINot listedSupportedSupportedSupportedSupportedNot listedNot listed
Supported Documented support Not listedPlatform details
RuntimesNode.jsBrowser / WASMPythonJVM.NETDart / FlutterNative

ChromeOS uses browser, Android or Linux-container apps. Mobile JavaScript uses React Native or Capacitor. Analytics availability varies by platform.

Find your SDK, runtime and framework

Operating systems
& environments

macOSWindowsLinux · glibc & musliOSiPadOSAndroidChromeOSBrowserLinux containers · Docker

ChromeOS uses browser, Android or Linux-container apps. Available languages and features vary by platform.

Runtimes

Node.js 20+
Native Node SDK on macOS, Linux and Windows.
Browser · WebAssembly
JavaScript and TypeScript in a worker, with OPFS and cross-origin isolation.
Python · JVM · .NET · Dart / Flutter
Language bindings and managed runtimes over the shared native engine.
Native applications
Swift, Objective-C, Go, Rust, C and C++.
Node.js · WebAssembly
@potluckdb/potluckdb-node-wasm exposes the lower-level Runtime Interface for bindings and specialized hosts.

SDKs & languages

Thirteen languages and Flutter. Familiar packages.

JavaScript · TypeScriptNode.js
@potluckdb/potluckdb
JavaScript · TypeScriptBrowser · WebAssembly
@potluckdb/potluckdb-browser
PythonPyPI
potluckdb
Java · KotlinJVM; Android package also available
dev.potluckdb:potluckdb-jvmdev.potluckdb:potluckdb (Android)
Swift · Objective-CSwift package
potluckdb-swift
Dart · Flutterthe Dart package registry
potluckdb
GoGo module
github.com/potluckdb/potluckdb-go
Rustcrates.io
potluckdb
C# (.NET)NuGet
potluckdb
C · C++Native application SDK
potluckdb-c-sdk
Optional analytics packages

@potluckdb/potluckdb-browser-analytics and @potluckdb/potluckdb-node-wasm-analytics include the analytical engine. Node's native SDK uses @potluckdb/potluckdb-analytics.

App frameworks

The supported framework and platform combinations.

FrameworkPlatformsPackage
ElectronmacOS · Linux · Windows@potluckdb/potluckdb
TaurimacOS · Linux · Windowspotluckdb · Rust
QtmacOS · Linux · Windowspotluckdb-c-sdk · C++
FluttermacOS · Linux · Windows · iOS · iPadOS · Androidpotluckdb · Dart
React NativeiOS · iPadOS · Android@potluckdb/potluckdb-react-native
Capacitor · IoniciOS · iPadOS · Android@potluckdb/potluckdb-capacitor
.NET MAUImacOS · Windows · iOS · iPadOS · Androidpotluckdb · C#

Standard database interfaces

Python DB-API · JDBC · ODBC

Connect existing tools to the same synchronized database.

Full platform and language matrix Includes platform-specific availability and analytics exceptions.

A BUCKET INSTEAD OF A SYNC SERVICE

Less infrastructure.
Lower running costs.

Sync through your storage bucket. Keep infrastructure costs to storage, requests and transfer, without running a dedicated sync service.

WebLocal SQLite
MobileLocal SQLite
DesktopLocal SQLite
Your bucket
Near-real-time sync. Your storage. No sync servers.
Amazon S3Cloudflare R2WasabiIDrive e2Google CloudAzure Blob

Also S3-compatible storage, including MinIO, and a local directory for development.
The potluckdb license is separate from your storage-provider bill.

How fast does automatic sync react?

Defaults batch outgoing changes for 30 ms and check for updates every 200 ms while active, or every second while idle. These are scheduling intervals; end-to-end arrival depends on the network and workload.

STORAGE, WITHOUT A SYNC-SERVER BILL

A terabyte.
From $6 a month.

Storage-only estimate · USD/month
1,000 GB of billable objects

Stored objects, not logical database size. Requests, downloads, retained versions, minimum billing and early deletion can change the bill. potluckdb license and taxes are separate.

Rates, conditions & sources

Monthly pay-as-you-go list rates checked 30 September 2026. This comparison models 1,000 GB of billable storage, no free-tier credits or introductory offers, and no extra request, download or deletion charges. Provider billing units and rounding may differ.

  • IDrive e2: $6/TB/month; 1 TB minimum. API calls are included; downloads up to 3× active storage are included, then $0.01/GB. No minimum retention period.
  • Wasabi: $7.99/TB/month. Minimum billing and storage-duration rules apply; early deletion can add charges. Free downloads are subject to its fair-use policy (monthly downloads no greater than active storage).
  • Cloudflare R2 Standard: $0.015/GB-month × 1,000. Egress is free; operations are billed separately. Free-tier credits are excluded here.
  • Amazon S3 Standard: US East (N. Virginia), first storage tier, $0.023/GB-month × 1,000. Requests and chargeable downloads are additional.

Compression may reduce the stored footprint; retained revisions and metadata may increase it. This is a comparison of storage rates, not a forecast for a specific app.

Full assumptions & policy sources ↗

MAKE YOUR APP FEEL IMMEDIATE

Fast from the first load.
Quick at every tap.

A compact browser core gets out of the way.
Local reads and writes keep the network off the path to a save.

SQLITE + SYNC
792 kBBrotli-compressed browser coreCore WASM · quality 11 · JavaScript and optional analytics separate
LOCAL OPERATIONSLower is faster

Save locally.
Keep moving.

Typical save · median
0.62 ms
99th percentile
1.70 ms

Local SDK write calls with S3 configured. Network sync and UI rendering are outside this timing.

Browser core measured from the release package. Local timings: published Python SDK run on EC2.Measurement details
Batch imports and more performance measurements

Bring data by the thousands.

Published run: 20,000 rows, 256-byte payloads, batches of 1,000.

SQLite
4,154 rows / second

Highest throughput in the published run.
S3 Express configured; inserts execute locally.

LOCAL BULK INSERTSHigher is faster
S3 Express One Zone
4,154 rows/s
Google Cloud Storage
3,759 rows/s
Cloudflare R2
3,721 rows/s
Local directory
3,469 rows/s
Azure Blob Storage
3,012 rows/s
Amazon S3
2,899 rows/s
Python SDK · 256-byte payloads · EC2 c7i.2xlarge · same workload, six storage configurations.Measurement details
Explore all published read, write and sync measurements

Local reads: about one tenth of a millisecond.

Median point read. Lower is faster. Blue highlights Amazon S3 as a reference configuration.

Local directory
0.095 ms
Amazon S3
0.105 ms
S3 Express One Zone
0.103 ms
Cloudflare R2
0.104 ms
Google Cloud Storage
0.106 ms
Azure Blob Storage
0.105 ms

Local operations with each remote configured; these are not bucket read latencies.

Download the measurements ↓

KEEP WORKING OFFLINE

The connection drops.
Your app keeps going.

Read and edit data already on the device.
Reconnect, and your changes are ready to sync.

TRY IT. EDIT ON EITHER DEVICE.
Your laptopLocal SQLite
Up to date
Your bucketChanges meet hereSync when connected
Your phoneLocal SQLite
Up to date

Connected. Add or remove a note on either device.

Interactive illustration · timing simplified

TRY THE REAL ENGINE

Big database.
Small transfers.

Fetch the pages you need. Sync compressed changes.
Try a read, a cached read and a one-row edit.

POTLUCKDB · LIVE IN YOUR BROWSER

ONE SHARED DATABASE

20,000 notes.
Just the rows you need.

A fresh sample, generated here.
No account. No cloud credentials.

A large database. A small read.

Whole SQLite database
Measured when you load
Downloaded for this read
—

Load the sample to measure the difference.

The engine loads only when you start. Your sample stays in this browser.

Your query resultWaiting for a query
IDTitleCategory
—Run the sample to see real rows.—
Transfer activityNo requests yet

Every request. Directly labeled bytes.

A request waterfall, measured locally.

See compression, measurements & setup

Smaller before it travels. Initial publication: — of SQLite pages becomes — of submitted payload. Run the sample to measure it. This combines compression and deduplication; it includes revision metadata.

The real potluckdb WebAssembly engine runs against an in-memory, S3-shaped demo bucket. Request bodies are measured, including metadata; HTTP headers, TLS and the engine download are excluded. The waterfall shows local operation timing, not internet latency. On-demand reads use prefetch disabled to isolate the pages needed by this query. SQL data includes repeated text and randomized content; results depend on the workload.

SELECT id, title, category FROM notes WHERE id BETWEEN 9951 AND 9970 ORDER BY id

Published cloud reference: 97.3 kB submitted for a 100-row S3 push with 256-byte payloads per row. Conditions and raw results ↗.

Sample data uses this browser’s private storage. Clear demo data removes this run’s files. Reloading starts a new run. The bundled engine is release 0.1.0-rc.df3809a06183.

Exact bytes & request trace
Run the sample to see the measured trace.
Methodology ↗

Real engine · local demo bucket · measured payload bytes

GET AHEAD OF THE NEXT READ

Read ahead.
Wait less.

Fetch pages on demand, then get ahead with parallel prefetching.
Keep fetched data locally for the next read.

More pages ready. Fewer waits in sequence.On-demand reads + parallel fetching + a local cache
See the controlled prefetch experiment

From 1.55 seconds to 317 milliseconds.

Open + full scan of a fresh snapshot. Lower is faster.

Prefetch off
1.55 s
Prefetch on
317 ms
4.9× faster in this controlled test

Controlled experiment · 4,096 rows · simulated 20 ms per object read · median of four fresh runs per mode.

Local adapter with simulated latency. Prefetch increased object requests from 72 to 105; this is not a cloud benchmark.

Parallel fetching and pushing do more work at once. Bounded prefetching brings upcoming pages into the cache.Conditions & raw results

REAL SQLITE. CONNECTED DATA.

Relationships. Constraints.
Transactions.

Join your tables. Enforce your rules.
Commit related changes together, with SQLite on the device.

THE SAME CAFÉ, UNDER THE HOODLive SQL · runs on demand
One order. One transaction.Sample data
01

Orders

id PRIMARY KEY
201
product_id FOREIGN KEY
1
quantity
1

A new order is recorded.

02

Products

name
Coffee
id PRIMARY KEY
1
stock CHECK ≥ 0
3

Available stock is reduced.

Both changes commit. Or neither does.

Start with 3 coffees in stock. Place an order—or try one the database should reject.

QUERY ACROSS TABLESorders JOIN products

#201 · Coffee · 1 cup · $4.00

See the SQL and supported scope

This runs the bundled potluckdb WebAssembly engine in your browser. The café here is a separate local example from the illustrative hero. Each order inserts a row and updates stock inside the SDK’s managed transaction. The stock CHECK rejects an oversized order; the transaction rolls back its new order too.

await db.transaction(async tx => {
  await tx.execute(
    "INSERT INTO orders(product_id, quantity) VALUES(?, ?)", [1, quantity]);
  await tx.execute(
    "UPDATE products SET stock = stock - ? WHERE id = ?", [quantity, 1]);
});

SELECT orders.id, products.name, orders.quantity
FROM orders JOIN products ON orders.product_id = products.id;

Foreign keys are explicitly enabled for this connection with PRAGMA foreign_keys=ON.

SQLite queries, relationships and transactions are supported within a single-main-database profile. ATTACH, DETACH, VACUUM and library-owned storage settings are excluded. Use the SDK transaction API and one statement per call. Local atomicity does not imply a distributed transaction across devices.

Checked features, exclusions & evidence ↗

JOINs · Foreign keys · Transactions · Indexes · Views · Triggers

CHANGES FROM MORE THAN ONE DEVICE

When two devices edit,
know what happens next.

One device syncs first. The other can re-apply its pending changes
to that newer version, following the SQL you wrote.

ONE CAFÉ · BOTH DEVICES START WITH 12 COFFEESInteractive illustration

Laptop Counter A

POTLUCK CAFÉ

Coffees left

8
12 − 4 = 8
Sold 4 coffees
Saved locally

Shared bucket

Last published stock

12Starting version

Phone Counter B

POTLUCK CAFÉ

Coffees left

11
12 − 1 = 11
Sold 1 coffee
Saved locally
Two sales. Saved on two devices.The laptop now has 8 coffees; the phone has 11. Neither has shared its sale yet.
Step 1 of 4

That’s replay: re-running the phone’s recorded SQL on the newer shared data.
Your app chooses when to resolve the conflict.

A change can’t be applied? Your app gets the decision.

A constraint failure or replay mismatch is set aside and reported, so your app can handle it explicitly.

See the SQL and exact conflict rules

The phone recorded a subtraction, not a replacement stock count:

UPDATE stock SET units = units - ? WHERE id = 1;
-- Recorded parameter: 1
-- On the newer shared value: 8 - 1 = 7

SQL expressions run again; parameters stay as recorded. If the phone had instead recorded SET units = ? with the value 11, applying that statement would set the count to 11. The result follows the operation your app recorded.

  1. Sync reports the conflict. Your app chooses when to call resolveConflict(); background sync does not silently resolve it.
  2. Adopt the latest shared revision. Transactions already published there are recognized and skipped.
  3. Replay the remaining local transactions in order. Recorded SQL runs with its original parameters. Expressions are evaluated against the new data; values calculated earlier in your application remain unchanged.
  4. Inspect the result, then publish. The result identifies already-published, replayed, quarantined and still-pending transactions. Call sync() to publish the successfully replayed work.

A constraint failure or replay mismatch rolls back that replay attempt, preserves it in quarantine and lets later transactions proceed. Temporary resource or storage errors can stop replay and leave work pending for a retry. Replay follows your SQL; it does not infer your application's intended merge.

Replay rules, example checks & source

Keep the history you need. Read retained revisions, set retention and storage budgets, and reclaim space with automatic compaction.

KEEP CONTROL OF YOUR DATA

Your data.
Your encryption keys.

Enable AES-256-GCM encryption before database pages leave the device.
Your application holds the key. Your bucket holds encrypted pages.

ON YOUR DEVICEtitle Release notesstatus Ready to shareowner Your application
AES-256-GCMYour key stays with your app
IN YOUR BUCKET••• ••••• ••••••••• ••• •••••••• ••••• •••
Encrypt on the device. Store with your provider.

Application-held keysKept in your keychain or secret store.

Key migrationRe-encrypt a retained revision with a new key.

Temporary credentialsShort-lived storage access, refreshed by the SDK.

Encryption is optional and protects published data. Local-device protection is separate.

DUCKDB'S EXECUTION ENGINE. YOUR DATA.

Turbocharge your
analytical queries.

Use the optional DuckDB engine to group, aggregate and analyze
a read-only snapshot of the same data.

5.2×

faster for this aggregation

One million rows. The same answer. Less waiting.

Grouped count, sum, minimum and maximum. Warm median; lower is faster.

SQLite engine
194 ms
DuckDB engine
37 ms

Local Windows experiment · native SDK · six warm samples per engine · identical results verified.

First-call DuckDB: 58.7 ms. Workload-specific comparison; engine and platform availability vary.Query, setup & raw results

ADVANCED CONFIGURATION · OPTIONAL

Add analytics near storage.
When you need it.

Run large analytical queries on your own compute near the bucket.
Only the results travel back to your app.

Your app

Web · Mobile · Desktop

Local SQLite stays local
SAME CLOUD REGIONCompute close to storage

Your query service

EC2 or similar compute

potluckdb SDK+ DuckDB execution engine

Your bucket

S3 or compatible storage

Scan near the data. Send back the answer.

Explore the SDKs ↗

Optional, customer-built setup. You provide the query endpoint and compute, sized for your workload. Compute and applicable transfer charges are additional. Architecture notes ↗

THE BENEFITS, TOGETHER

What you gain.
At a glance.

Your benefitWhat makes it possibleDetails & evidence
Build across platformsFamiliar SQLite and ready-made SDKs for web, mobile, desktop and server apps.Languages, frameworks, runtimes and operating systems.
Explore the support matrix ↗
Model real app dataJOINs, foreign keys, transactions, indexes, views and triggers. Import records in batches.Try relationships & transactions ↗
See the 20,000-row import benchmark ↗
Make every tap feel fastRead and write locally, with a compact browser engine. Save without waiting for a network round trip.0.62 ms local writeMedian · native Python SDK on EC2 · S3 configured. Excludes sync and UI rendering.792 kB Brotli core & timing details ↗
Keep working offlineRead and edit locally available data. Reconnect to share pending changes through your bucket.Connected sync runs in the background.
Try disconnecting the devices ↗
Run less infrastructureNo dedicated sync server. Use S3, R2, Wasabi, IDrive e2, Google Cloud Storage, Azure Blob or compatible storage.Provider bills storage, requests and transfer. potluckdb license is separate.
Compare storage costs ↗
Move less. Load smarter.Delta sync, compression and deduplication. Parallel fetching and pushing, bounded prefetching and local caching.Measure transfers with the live engine ↗
See the prefetch experiment ↗
Add powerful analyticsOptional DuckDB execution. For larger workloads, run your own query service near storage and return results to the app.5.2× faster aggregation1 million rows · warm native Windows query · DuckDB vs SQLite in the measured workload.See the comparison ↗ · Optional setup ↗
Keep your data yoursOptional AES-256-GCM encryption with application-held keys. Key migration and refreshable, short-lived storage credentials.Protects published data; local-device protection is separate.
See how encryption works ↗
Understand concurrent editsReplay recorded SQL on newer shared data. Constraint failures and replay mismatches are set aside and reported.Your app decides when to resolve and how to handle failures.
Follow two devices through a conflict ↗
Keep useful historyRead retained revisions, set retention and storage budgets, and reclaim local space with automatic compaction.Read-only snapshots of retained revisions.
Explore the documentation ↗

Measurements describe the linked workloads, not every app or platform. SDK and optional-engine availability vary by platform; see the support matrix and documentation.

Pricing

Free for personal projects. Simple plans for teams.

One seat per developer. People who use your apps never need a seat.

See plans and pricing

Personal

Free

For learning, hobby projects and free apps you publish yourself. One seat.

Get a free key

Professional · Monthly

USD 99 per seat / month

For work and commercial products. Cancel any time.

Buy monthly

Professional · Annual Best value

USD 499 per seat / year

Launch price. The regular price will be USD 999. Yours stays at USD 499 while you renew.

Buy annual

Trying it at work? Every install runs for 30 days without a key. No sign-up. Start the trial

Prices plus tax where applicable.