Does SQLite Work With Cloudflare Pages?

Partially CompatibleLast verified: 2026-02-26

SQLite works with Cloudflare Pages, but only in serverless functions (Workers) with constraints—not natively on the static hosting layer.

Quick Facts

Compatibility
partial
Setup Difficulty
Moderate
Official Integration
No — community maintained
Confidence
high
Minimum Versions

How SQLite Works With Cloudflare Pages

SQLite can be used with Cloudflare Pages through Cloudflare Workers, which power Pages Functions. However, there's a critical limitation: Workers run in V8 isolates without persistent filesystem access, so you can't use traditional SQLite bindings directly. Instead, you'll use sql.js (a JavaScript port of SQLite) or Cloudflare's D1 product, which is a managed SQL database purpose-built for Workers. If you choose sql.js, the database exists in-memory or can be serialized to/from storage, making it suitable for read-heavy, low-concurrency applications. For production applications with persistence requirements, D1 is the recommended path—it's essentially managed SQLite with global replication. Your Pages Functions can call Workers functions that query D1, creating a viable serverless SQL stack. The developer experience is smooth if you accept the architectural constraints: no traditional file-based persistence, eventual consistency across regions, and pricing based on request volume rather than storage.

Best Use Cases

Content management for static sites with dynamic data (blog post metadata, product catalogs)
Read-heavy applications with infrequent writes (analytics dashboards, documentation indexes)
Rapid prototyping of full-stack apps without setting up external databases
Multi-tenant applications using D1's namespace isolation

Using D1 with Pages Functions

bash
npm install --save-dev wrangler @cloudflare/workers-types
typescript
// functions/api/posts.ts
export const onRequest: PagesFunction<{ DB: D1Database }> = async (context) => {
  const { request, env } = context;
  
  if (request.method === 'GET') {
    const { results } = await env.DB.prepare(
      'SELECT id, title, slug FROM posts ORDER BY created_at DESC LIMIT 10'
    ).all();
    
    return new Response(JSON.stringify(results), {
      headers: { 'Content-Type': 'application/json' },
    });
  }
  
  if (request.method === 'POST') {
    const { title, slug } = await request.json();
    const { success } = await env.DB.prepare(
      'INSERT INTO posts (title, slug) VALUES (?, ?'
    ).bind(title, slug).run();
    
    return new Response(JSON.stringify({ success }), { status: 201 });
  }
};

// wrangler.toml
[[env.production.d1_databases]]
binding = "DB"
database_name = "pages-db"
database_id = "your-database-id"

Known Issues & Gotchas

critical

SQLite file persistence doesn't work in Workers—no filesystem access in isolates

Fix: Use Cloudflare D1 for persistence, or use sql.js with in-memory storage for read-only/cache use cases

warning

sql.js has performance overhead; loading large databases into memory is slow

Fix: Keep databases under 10MB, use D1 for larger datasets, or implement pagination/filtering at query time

warning

Cold starts and execution time limits (default 10ms for free tier, up to 50ms paid) may cause timeouts

Fix: Optimize queries, use indexes, consider caching results, upgrade to higher plan if needed

info

D1 is in public beta and pricing/features may change

Fix: Monitor Cloudflare announcements; maintain abstraction layer in code for easy migration if needed

Alternatives

  • Cloudflare Pages + Cloudflare Workers KV (key-value store, faster but schema-less)
  • Vercel + Neon PostgreSQL (traditional serverless SQL, larger ecosystem)
  • Netlify + Supabase (managed PostgreSQL with real-time subscriptions)

Resources

Related Compatibility Guides

Explore more compatibility guides