TL;DR:

  • Running compute at the edge while querying a centralised database defeats much of the latency benefit — edge-native databases solve this by placing data close to users
  • Turso (built on libSQL, a fork of SQLite) and Cloudflare D1 (SQLite-compatible) are the two most mature options, each with distinct architecture trade-offs
  • Best suited for read-heavy workloads with regional data that can tolerate eventual consistency; not yet a replacement for strongly-consistent transactional databases

The premise of edge computing is straightforward: move processing closer to users, cut latency, improve the experience. Cloudflare Workers, Fastly Compute, and Deno Deploy make it easy to run JavaScript or WebAssembly at dozens of locations worldwide. Response times drop from hundreds of milliseconds to single digits.

Then your edge function queries a database in us-east-1, and you’re back to 200ms.

This is the edge data problem. And it’s where a new category of edge-native databases comes in.

Why centralised databases undermine edge compute

Latency from a Cloudflare Worker to a PostgreSQL instance in AWS Virginia might be 40–150ms depending on the user’s location — before your query even starts executing. For a user in Singapore or São Paulo, it’s worse. The round trip to the database can dwarf the edge function’s execution time.

The obvious workaround — caching at the edge — works for static or slowly-changing data. It doesn’t help for queries that depend on fresh data, user-specific state, or writes that need immediate consistency.

Edge-native databases take a different approach: replicate the database itself to the edge. The data lives alongside the compute, at or near the CDN PoP. Queries execute locally, returning in sub-millisecond time.

Turso: SQLite at global scale

Turso is built on libSQL, an open-source fork of SQLite maintained by the Turso team. SQLite is an unusual choice for a distributed database — it was designed for embedded, single-process use. But its simplicity, reliability, and the breadth of SQLite tooling make it an attractive foundation.

Turso extends SQLite with a client-server protocol, multi-tenancy, and a global replication layer. The architecture:

  • Primary database hosted in a region you choose
  • Replicas deployed to Turso’s 30+ global edge locations
  • Reads served from the nearest replica — typically sub-5ms for most users worldwide
  • Writes go to the primary and propagate to replicas asynchronously

This means reads are fast globally; writes are fast only if the user is near the primary. For workloads that are 80–95% reads (typical for content delivery, product catalogues, user preferences), this is a good trade.

Turso’s pricing model is database-instance based, which suits the use case many modern architectures actually have: one database per customer tenant (multi-tenancy at the schema level rather than row level). A SaaS product with 10,000 customers can have 10,000 isolated Turso databases, each replicated globally, without cross-tenant data leakage risk.

import { createClient } from "@libsql/client";

const client = createClient({
  url: process.env.TURSO_DATABASE_URL,
  authToken: process.env.TURSO_AUTH_TOKEN,
});

const result = await client.execute(
  "SELECT * FROM products WHERE category = ?",
  ["electronics"]
);

The libSQL client works in Cloudflare Workers, Deno Deploy, and most edge runtimes. Driver compatibility with SQLite means existing SQLite queries typically work without modification.

Cloudflare D1: SQLite integrated into Workers

D1 is Cloudflare’s own edge database offering, built into the Workers platform. Also SQLite-compatible, also globally distributed — but with a different architecture: D1 runs the primary in Cloudflare’s network and serves reads from replicas at Workers PoPs.

The main advantage of D1 is platform integration. Your Worker reads from D1 with no network hop at all — the database is co-located with the compute in the same PoP. Binding is declared in wrangler.toml:

[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "xxxx-xxxx-xxxx"

And used in your Worker:

export default {
  async fetch(request: Request, env: Env) {
    const result = await env.DB.prepare(
      "SELECT * FROM users WHERE id = ?"
    ).bind(userId).all();
    return Response.json(result.results);
  }
};

D1 is simpler to operate if you’re already on Cloudflare — no additional authentication, billing, or network configuration. The limitation: D1 is Cloudflare-specific. Turso is portable across edge platforms.

D1’s consistency model has improved significantly — it now offers read replication with strong consistency for most operations, and the eventual consistency window for replica reads is typically under a second.

The consistency trade-off

Both platforms offer eventual consistency for reads from replicas. In practice, “eventual” usually means milliseconds to a few seconds. For most use cases — product pages, content, user profile reads — this is acceptable.

Where it breaks down: financial transactions, inventory management, booking systems, or any domain where a user writes data and immediately expects to read their own write consistently. For these, you still want a strongly-consistent centralised database (PostgreSQL, CockroachDB, PlanetScale) and you accept the latency.

The pragmatic architecture: use an edge-native database for the data that benefits from edge distribution (product catalogue, CMS content, user preferences, session data), and a centralised database for the data that requires strong consistency (orders, payments, inventory).

When to use edge-native databases

Good fit:

  • Globally distributed user bases with read-heavy access patterns
  • Multi-tenant SaaS with isolated per-tenant data
  • APIs serving static or slowly-changing data that currently relies on caching hacks
  • Jamstack and edge-rendered sites that need personalisation without centralised DB round trips

Poor fit:

  • High write volumes requiring immediate cross-region consistency
  • Complex JOIN queries across large datasets (SQLite handles these but isn’t optimised for analytics)
  • Existing PostgreSQL workloads with extensive use of PostgreSQL-specific features

The landscape is moving fast

Both Turso and D1 have shipped substantial improvements in the past six months. Turso added vector search (useful for AI-powered edge apps), and D1 has closed most of the gap on PostgreSQL feature parity for common operations. Neither is a replacement for a mature OLTP database in all scenarios — but for the right workloads, the latency improvements are dramatic enough to justify the architectural change.

If your edge functions are still round-tripping to a centralised database, this is the next optimisation worth evaluating.