No server of your own · Real per-user login · $0 when idle

Ship apps with no backend at all.

Not serverless functions. Not a backend-as-a-service SDK. No server of your own to run. Your app is a folder of static files. jaydb is the login and the database — your users sign in with their own identity and the browser reads and writes their data directly. Nothing sits in the middle.

Free forever: 1 GB, 100k reads and 10k writes every month. Hard stops on the free tier — never surprise bills.

The whole request path
  1. Your app Static files on a CDN HTML · JS · CSS — nothing to run
  2. Sign in Your user, their identity Google · GitHub · Microsoft · OIDC — via acme.jaydb.com
  3. Token Browser gets its own bearer token PKCE — no client secret ever ships to the browser
  4. Data Browser talks straight to jaydb GET/PUT acme.jaydb.com/v1/n/app/docs/… with Bearer

No API server, no auth service, no session store — the browser reaches jaydb directly, and every user acts as themselves.

Why you can rely on it

0 servers

to run, patch, or scale

No API tier, no auth service, no session store. Your app is static files; jaydb is everything behind them.

Real login

Users sign in as themselves

A per-tenant OIDC issuer with PKCE. Bring Google, GitHub, Microsoft, or any OIDC provider — no secret in the browser.

$0

Cost while idle

No instance to keep warm. Spin up 50 prototypes or side projects, pay only for active traffic.

MIT license

100% Open source

Self-host the same Go engine anytime, export plain JSON. View on GitHub.

The shift

Delete the backend. Keep the app.

Every app used to need a server in the middle: something to check who you are, something to hold the session, something to talk to the database, and a pipeline to deploy and keep it all alive. jaydb takes over that whole layer — so the boxes below simply stop existing.

What you no longer run

  • Auth service→ per-tenant OIDC issuer, built in
  • Session store→ each browser holds its own token
  • API server & routes→ the browser calls the data plane directly
  • ORM & migrations→ write-to-exist JSON documents
  • Connection pool→ stateless HTTP, nothing to exhaust
  • Server deploy pipeline→ push static files to any CDN
  • Always-on instance bill→ $0 while idle

What's left to ship

index.html app.js styles.css

A folder of static files and a jaydb tenant. Drop it on GitHub Pages, S3, Netlify, a Cloudflare bucket — anywhere that serves files. There is no server process to start, so there is nothing to keep running, nothing to autoscale, and nothing to page you at 3 a.m.

“Serverless” functions still boot a server for each request. This has no server at all — the only always-on thing is jaydb, and you don't run that either.

Identity, without an identity server

Your users sign in as themselves — and that's what makes it possible

A frontend-only app can't keep a secret. The reason it can still be safe is that nobody ships one: every organization gets its own OIDC issuer at <org>.jaydb.com, and each end-user signs in through it with standard Authorization Code + PKCE. The browser walks away with a token scoped to that one user. No shared API key in your JavaScript, ever.

A perfect fit: apps your AI builds

And when an AI writes the app, it writes it frontend-only too

A no-backend app is exactly what an AI assistant can ship end to end. No server to scaffold, no migrations to fail, no connection pool to configure — just static files plus jaydb for sign-in and storage. Give your assistant the storage layer and it builds the whole thing.

Write-to-exist

No database creation step. No SQL migrations to generate or fail. The first PUT to a key creates the namespace and collection automatically.

fetch is the entire SDK

Three standard HTTP verbs and one header. No package to install, no version conflicts, no client wrapper to keep in sync — nothing an AI can get wrong.

Safe for parallel writes

Every write carries an ETag version check. Multiple users or background tasks updating the same document won't silently clobber each other.

Learnable in one context window

The full API fits in /llms.txt — a single file any LLM can consume. No crawling docs, no guessing endpoints. See the full spec.

paste into your AI prompt, system instructions, or .cursorrules
# Instruction for your AI to add persistent backend storage:
You have access to persistent key-value storage at:
BASE_URL: https://<tenant>.jaydb.com/v1/n/app/docs
HEADER: X-JayDB-API-Key: $JAYDB_KEY

- Read data: GET $BASE_URL/<key> (Keep the ETag response header)
- Save data: PUT $BASE_URL/<key> with JSON body
- Safe update: PUT $BASE_URL/<key> with Header "If-Match: <etag>"
- List keys: GET $BASE_URL?list&prefix=<prefix/>

Reach for it when

  • An AI agent needs to add storage to an app it is building.
  • Multiple users or workers share documents safely.
  • State belongs to a user, a session, or a tenant.
  • Idle projects should cost $0.
  • You want to self-host the same engine later.

Use something else when

  • You need joins or foreign-key constraints.
  • Writes must be atomic across multiple documents.
  • You query by field values — there are no secondary indexes.
  • You need full-text search or aggregation.
  • One key takes sustained concurrent writes from many writers.

Getting started

Three steps. Under a minute.

No schema, no migration, no connection pool, no instance to size.

  1. Create a namespace

    One click. You get a URL and an API key, and no card is asked for at any point.

  2. Write a document

    One PUT to a key of your choosing. The namespace exists the moment you write to it.

  3. Read it from anywhere

    By key or by prefix. Every response carries an ETag, so two writers cannot silently overwrite each other.

The data model

A tree of documents for any application

Keys are slash-separated paths, every path holds a JSON document, and branches form collections. See how real-world workloads map cleanly without schemas, migrations, or ORMs.

Autonomous multi-agent state, persistent memory, and step execution traces.

acme.jaydb.com/v1/n/app/docs
Document Tree Click node to inspect
GET https://acme.jaydb.com/v1/n/app/docs/ agents/researcher/config
etag a81f09e1 184 B Content-Type: application/json
Write-to-exist: Agents initialize their own system prompt and tool config dynamically.

Key is the REST URL

No tables or column schemas. A document key like tenants/acme/users/101 is identical to the HTTP endpoint you fetch or PUT to.

Scoped Prefix Queries

List any branch in one call with prefix=agents/run-91/steps/. Deeply nested collections without secondary indexing overhead.

Isolated Concurrency

Every document node has its own version tag (ETag). Updating tasks/101 never blocks or locks someone updating tasks/102.

The model

One API you already know how to use

A key holds a JSON document. Read it, write it, or swap it atomically. That's the whole surface — and the pricing is just as simple.

  • Pay only for what runs

    No monthly minimum. Idle projects cost zero. A typical app with 5M reads and 1M writes runs about $2.43/mo — less than half what Firestore charges for the same workload.

  • Simple pricing units

    One read is one read, regardless of document size. No 4 KB tranches, no per-second capacity, no surprise multipliers when your documents grow.

  • Built-in collision safety

    Every response carries a version. Send it back on write and the server rejects the request if someone else wrote first — no lock servers, no transaction coordinators.

write · read · compare-and-swap
# create — fails with 412 if the key already exists
curl -X PUT https://acme.jaydb.com/v1/n/app/docs/users/101 \
  -H "X-JayDB-API-Key: $JAYDB_KEY" \
  -H "If-None-Match: *" \
  -d '{"name":"Alice","plan":"free"}'

# read it back — the ETag comes with it
curl https://acme.jaydb.com/v1/n/app/docs/users/101 \
  -H "X-JayDB-API-Key: $JAYDB_KEY"

# update only if nobody moved it since
curl -X PUT https://acme.jaydb.com/v1/n/app/docs/users/101 \
  -H "X-JayDB-API-Key: $JAYDB_KEY" \
  -H 'If-Match: "3f9a1c72"' \
  -d '{"name":"Alice","plan":"pro"}'

Multi-user state without running a backend

Two people (or two agents) editing the same document can't silently overwrite each other. The version check handles it — no WebSocket server, no realtime subscription to manage.

read-modify-write with retry
// Apply `mutate` to a document, retrying when someone else wins the race.
async function update(key, mutate, attempts = 5) {
  for (let i = 0; i < attempts; i++) {
    const res = await fetch(`${BASE}/${key}`, { headers });
    const doc = res.ok ? await res.json() : {};

    // If-Match on an existing doc; create-only when there is none yet.
    const guard = res.ok
      ? { 'If-Match': res.headers.get('ETag') }
      : { 'If-None-Match': '*' };

    const put = await fetch(`${BASE}/${key}`, {
      method: 'PUT',
      headers: { ...headers, ...guard },
      body: JSON.stringify(mutate(doc)),
    });

    if (put.ok) return put.json();
    if (put.status !== 412) throw new Error(await put.text());
  }
  throw new Error('too much contention on ' + key);
}

// Two people adding a card to the same board cannot clobber each other.
await update('boards/42', (b) => ({ ...b, cards: [...(b.cards ?? []), card] }));

Cost

One workload. Six platforms. Your math.

20 GB stored, 5M reads, 1M writes/month, 8 KB documents. Published rates, free tiers applied, arithmetic you can redo.

jaydb $2.43
Firestore $4.26
DynamoDB on-demand $6.25
Upstash Redis $15.94
Supabase Pro $25.00
Convex $25.14

Assumptions, stated so you can check them: US East list prices and every platform's free tier applied, including the ones more generous than ours. DynamoDB reads are strongly consistent, so an 8 KB document is 2 read units and 8 write units. Convex meters function calls, database I/O and storage, and all three are counted here. Supabase Pro is a floor rather than a usage figure — this workload fits inside it, and a fourth developer would make it $100 on Convex Pro. Egress is excluded for every platform including ours: at 8 KB a read this workload moves roughly 40 GB, which would add about $3.60 on Firestore and nothing here, where egress is included.

Published rates, retrieved 10 August 2026. Where a platform does not sell a unit, the cell says so rather than guessing an equivalent.
Platform Monthly floor Storage /GB-mo Reads Writes Egress
jaydb $0 $0.05 $0.20 /M $0.50 /M included
Firestore $0 $0.15 $0.30 /M $0.90 /M $0.12/GiB over 10 GiB
DynamoDB on-demand $0 $0.25 $0.125 /M RRU $0.625 /M WRU not published
Supabase $25 $0.125 over 8 GB no per-read charge no per-write charge $0.09/GB over 250 GB
Convex $0, Pro $25/developer $0.20–0.22 I/O $0.22/GB + $2.20/M calls same metering $0.132/GB over 1 GB
Upstash Redis $0 $0.25 $2.00 /M commands $2.00 /M commands $0.03/GB over 200 GB

Where the others win, and why we say so: Firestore's free tier is far more generous than ours at 50k reads a day, and DynamoDB's per-unit read price is lower than ours. The difference shows up in the totals because their units are smaller than a document — and because index-entry reads, a one-read minimum per query, per-region write billing and hourly compute all land on the invoice without appearing on the rate card. Sources: Firestore, DynamoDB, Supabase, Convex, Upstash.

Console

Browse and edit your data live

Explore the key hierarchy, edit documents in place, and see exactly what you're spending. Included with every namespace — nothing to install.

Illustration of the Explorer: a key hierarchy on the left with users, boards and sessions prefixes, and the selected document users/101 opened as editable JSON on the right, showing its current ETag.

Illustrations of the console, drawn in the page rather than screenshotted — the numbers are an example workload, not live data.

Pricing

Metered in the smallest unit there is

The rates are quoted per million because that is readable. The meter underneath counts single operations and megabyte-hours, so there is no threshold to cross and nothing to round up to.

Free every month, forever

1 GB stored, 100,000 reads and 10,000 writes. Not a trial and not a credit that expires — it applies to every account, every month. On the free plan usage stops at the allowance instead of billing you, so no card is needed to start.

Storage metered per megabyte-hour $0.05 / GB-month
Reads metered per single read $0.20 / million
Writes metered per single write $0.50 / million
Deletes removing data is never billed free
Egress fair use, no per-GB bandwidth line included

$5

Prepays $6.50 of metered usage. A 1.3× discount, and nothing changes about how you are metered.

$10

Prepays $15 of metered usage. A 1.5× discount, for when the meter is regularly past the smaller pack.

There is no monthly floor, no per-seat charge and no tier that unlocks a feature. Packs are a discount on the same meter, so crossing one changes only the price you already paid — never what your application is allowed to do.

What would your month cost?

Storage$0.00

Reads$0.00

Writes$0.00

Your month $0.00

The same workload on Firestore: $0.00

Architecture

Why it can be this cheap

The price is not a promotion. It follows from two decisions about where data lives and how writes agree with each other.

hot tier

Reads come from memory

Recently touched documents are served from an in-memory cache. Concurrent requests for the same key collapse into a single backend fetch — a hundred readers cost one storage read, not a hundred.

That's why cost stays flat as traffic grows: the expensive layer sees a fraction of your actual request volume.

cold tier

Durable storage without always-on servers

Documents live in object storage — that's where both the durability and the low price come from. No cluster to keep running, no replica on standby, nothing that bills you while your project sleeps.

A conventional database keeps machines running for indexes and transaction state. That fixed cost is the floor you pay whether or not anyone uses your app.

The trade-off, stated honestly

JayDB uses optimistic concurrency instead of locks. When you read a document you get its version; when you write, you submit against that version. If someone else wrote first, you get a rejection and retry.

A traditional database keeps a lock manager and transaction coordinator running at all times, provisioned for peak contention. That infrastructure runs whether or not contention ever happens — and you pay for it.

Most app workloads are low-contention. Two users rarely write the same document in the same millisecond. When they do, one retry settles it. JayDB charges for the case you actually have, not the worst case you might.

The limit: under sustained concurrent writes to a single hot key, retries pile up and you want a database that takes locks. This page says so upfront rather than burying it.

Frequently asked questions

Everything you need to know

Clear answers on pricing, concurrency, self-hosting, and architecture.

Is it safe for a static site to talk to the database directly?

Yes — because no shared secret ships to the browser. Your app is a public PKCE client, so instead of embedding an API key, each end-user signs in through your org's OIDC issuer and the browser receives a bearer token scoped to that user. There is nothing confidential in your JavaScript to steal, and one user's token can't act as another. PKCE (proof key) replaces the client secret entirely.

How is this different from “serverless” or a backend-as-a-service?

“Serverless” functions still boot a server per request that you write, deploy, and debug. A BaaS SDK still runs code you configure and version. jaydb removes the layer itself: the browser calls a standard HTTP data plane directly, authenticated by an OIDC token from a per-tenant issuer you didn't build. The only always-on system is jaydb — and you don't operate that either. If you want a server, you can add one with an X-JayDB-API-Key; you just never have to start with one.

Which identity providers can my users sign in with?

Google, GitHub, Microsoft, any generic OIDC provider, or a custom OAuth2 provider. Org admins connect their upstream providers and register browser apps (client ID, redirect URIs, allowed origins) from the console. Every organization gets its own issuer at https://<org>.jaydb.com, with discovery metadata and a JWKS published under it.

Will I be charged unexpectedly on the free plan?

Never. The free plan includes 1 GB of storage, 100,000 reads, and 10,000 writes every month with a hard stop. When you reach the limit, requests return a rate-limit status instead of charging a credit card. No credit card is asked for when signing up.

How does JayDB prevent race conditions and write collisions?

JayDB uses standard HTTP ETag headers for Compare-And-Swap (CAS) optimistic locking. Every read returns the document's current version tag. When updating, your app passes If-Match: <etag>. If another user or agent updated the document in the meantime, JayDB rejects the write with 412 Precondition Failed, allowing your client to re-read and retry safely without lock managers.

Can I self-host JayDB on my own infrastructure?

Yes. The core JayDB engine is 100% open source under the MIT license on GitHub. You can embed the Go package directly into your application or run the standalone server binary backed by AWS S3, Cloudflare R2, MinIO, or local disk storage.

Why is JayDB so much cheaper than Firestore or Supabase?

Traditional databases keep always-on compute instances, replication clusters, and lock managers running 24/7, creating a high monthly cost floor. JayDB stores durable cold data in ultra-low-cost object storage (S3) at $0.05/GB-mo and serves hot traffic from an in-memory singleflight cache. When your app is idle, you pay $0.

What languages and frameworks work with JayDB?

Because JayDB is accessed over standard REST HTTP, it works in any language or runtime without installing an SDK: JavaScript, TypeScript, Python, Go, Rust, Ruby, PHP, Next.js, Node.js, Cloudflare Workers, Deno, Bun, and cURL.

Get started in 30 seconds

Stop running a backend. Start shipping.

Real per-user login and persistent storage for a static site — no server of your own, zero setup, and $0 idle cost.

Free forever: 1 GB, 100k reads & 10k writes every month. Hard stops instead of surprise bills.