How to Host SQLite Online for a Real Web App

Glowing SQLite database connected to a web dashboard and cloud servers.

SQLite is easy to run locally. The difficult part starts when your web app needs shared access, backups, authentication, and reliable deployment.

You can host SQLite online in several ways. Use a managed SQLite service, attach a database file to your application host, or deploy an edge database built around SQLite. The right option depends on your runtime, traffic pattern, write volume, and recovery requirements.

Start with the database model, then choose the provider. The cheapest option is not useful if it cannot handle your write pattern.

What It Means to Host SQLite Online

A hosted SQLite database is still based on SQLite or a compatible implementation. The difference is where the database file runs and how your application reaches it.

A local SQLite database usually looks like this:

./data/app.db

Your application opens that file directly. When the database is online, your application may connect through a hosted API, a database URL, or a replicated file system.

Local file versus managed database

A managed service stores the database for you. It usually provides authentication, backups, replication, connection tools, and a dashboard. Turso/libSQL and Cloudflare D1 fit this model.

A host-attached database keeps the SQLite file close to your application. Fly.io with LiteFS fits this model. You manage more of the deployment, but your app can continue using SQLite through a local file path.

The connection style affects your code. A managed provider usually requires a client library or platform binding. A host-attached database can often use your existing SQLite driver.

SQLite still has write limits

SQLite is not a traditional client-server database. It doesn’t accept unlimited concurrent writes.

In WAL mode, readers can continue while a writer changes the database. SQLite still normally allows one active writer at a time. The official SQLite WAL documentation explains how readers and writers operate concurrently.

This works well for many applications with short transactions. It becomes a problem when requests hold write locks for too long, run large imports, or create heavy write contention.

Use SQLite for small and medium workloads when the access pattern fits. Move to PostgreSQL or another server database when you need many independent writers, complex reporting workloads, or broad relational tooling.

Pick the Right Online SQLite Model

Your deployment target should decide the first shortlist.

Managed SQLite services

Choose a managed service when you want to deploy quickly and avoid maintaining database machines. Your provider handles the storage layer and gives your application a remote connection method.

This model fits:

  • SaaS prototypes that need a shared database
  • Small APIs with predictable traffic
  • Multi-tenant applications with separate databases
  • Edge applications that need data near users
  • Teams that don’t want to maintain replication

The main tradeoff is provider-specific behavior. A hosted SQLite service may add replication, connection pooling, or a modified protocol. Test your ORM, migrations, transactions, and backup workflow before committing.

SQLite on your application host

A host-attached database fits teams that already control their infrastructure. You can run the app and database on the same platform, then add replication when you need additional readers.

This model gives you more control over the file and runtime. It also gives you more operational work. You need to manage persistent storage, failover, backups, migrations, and deployment ordering.

Don’t place a SQLite file on an ordinary ephemeral container and assume it will survive a restart. The storage must be persistent, and the application must know which instance owns writes.

Host SQLite Online With Turso and libSQL

Turso Cloud documentation is a practical starting point for teams that want SQLite-compatible databases with a hosted control plane.

Turso uses libSQL, a SQLite-compatible database technology. Its service supports remote connections, database management, replication options, and usage-based plan limits. It is a natural choice for Node.js, serverless, edge, and multi-tenant applications that don’t need a full PostgreSQL server.

Basic connection setup

Install the TypeScript client:

npm install @libsql/client

Create a server-side connection:

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


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


const result = await db.execute({
  sql: "SELECT id, email FROM users WHERE id = ?",
  args: [userId],
});

Keep the URL and authentication token on the server. Don’t send them to browser code. Your frontend should call your application API instead.

The Turso TypeScript quickstart covers installation, remote connections, queries, and local development.

Current plan details and workload fit

As of September 2026, the public Turso plan table lists a free tier with 5 GB of storage, 500 million row reads per month, and 10 million row writes per month. Paid tiers increase storage, read capacity, write capacity, database counts, and point-in-time restore windows.

The published Developer tier is listed at $4.99 per month, while higher tiers are listed at $24.92 and $416.58 per month. Provider pricing, quotas, and plan definitions can change, so verify the current pricing page before launch.

Turso works well when you want a hosted database with explicit usage accounting. Track row reads and writes instead of assuming a database request equals one billable operation. A query that scans many rows can use more allowance than a query that returns one indexed row.

Use indexes, short transactions, and bounded result sets. Test write-heavy endpoints under realistic concurrency.

Use Cloudflare D1 With Workers

Cloudflare D1 is a managed SQLite database built for Cloudflare Workers. It is a strong fit when your API already runs on Workers and you want database access through a Worker binding.

It is less natural for a conventional server that expects a standard TCP database connection. D1 is designed around Cloudflare’s runtime and request model.

Create a database and binding

The setup process begins with a D1 database and a Worker binding. Cloudflare’s D1 getting started guide covers the account, database, and Worker configuration steps.

A Worker query looks like this:

export default {
  async fetch(request, env) {
    const result = await env.DB
      .prepare("SELECT id, email FROM users WHERE id = ?")
      .bind("user_123")
      .all();


    return Response.json(result.results);
  },
};

The DB value comes from the binding in your Worker configuration. It is not a public database URL.

Store schema changes as migration files instead of editing production tables manually. Cloudflare’s D1 migration documentation describes the SQL-file workflow.

Check the limits before launch

Cloudflare’s published limits list a 500 MB maximum database size on the Workers Free plan and 10 GB on Workers Paid. Account storage limits, database counts, queries per invocation, and recovery windows also vary by plan.

The free plan currently lists 5 million rows read per day, 100,000 rows written per day, and 5 GB of total storage. Paid pricing includes monthly read and write allowances, followed by usage charges.

D1 also limits the number of simultaneous connections per Worker invocation. That is different from opening unlimited connections across your entire system. Review the current D1 limits before designing a connection-heavy application.

D1 fits read-heavy APIs, small SaaS products, documentation tools, dashboards, and applications already using Workers. Keep write transactions short. Avoid treating it like a general-purpose database server.

Run SQLite on Fly.io With LiteFS

Fly.io’s LiteFS is a different approach. It replicates SQLite databases across Fly Machines while allowing the application to work with a local database path.

The LiteFS documentation describes it as a distributed file system that replicates SQLite databases. You deploy the application and storage infrastructure instead of purchasing a fully managed database product.

How the deployment works

Your application reads and writes through SQLite as usual. LiteFS handles replication at the file-system layer. A primary instance generally handles writes, while other instances can serve reads depending on your configuration.

This model can reduce network database latency because the application talks to a local file. It also requires careful handling of primary ownership, machine restarts, persistent volumes, and failover.

LiteFS is a good fit when:

  • Your team already deploys on Fly.io
  • You want SQLite close to the application process
  • Your workload has one clear write authority
  • You can operate persistent volumes and replicas
  • You need more infrastructure control than a managed service provides

It is not the easiest first option for a small team that wants a database endpoint and automatic operations. The infrastructure pricing is separate from database usage pricing, so calculate Machines, storage, backups, and bandwidth together.

Prepare SQLite for Production

Hosting the database is only one part of the deployment. You also need controls around data changes and recovery.

Use WAL carefully

Enable WAL when your hosting model supports it:

PRAGMA journal_mode = WAL;
PRAGMA busy_timeout = 5000;

WAL can improve reader and writer overlap. It doesn’t remove the one-writer limit. A five-second busy timeout also doesn’t fix a transaction that performs unnecessary work.

Keep transactions short. Do not make an external API call while holding a write transaction. Validate input first, then open the transaction, write the records, and commit.

Use indexes for common lookups. Avoid returning unbounded rows from API endpoints. Paginate administrative screens and export jobs.

Plan backups and restores

A backup is useful only if you can restore it.

Managed providers may offer point-in-time recovery, but the recovery window depends on the plan. Current published examples include up to seven days for D1 on the Free plan and longer periods on paid options. Turso plan limits also vary by tier.

For a self-managed database, schedule consistent backups. Copying only the main .db file while WAL changes are active may not capture the complete state. Use SQLite’s backup tools or a provider-supported snapshot process.

Test a restore into a separate environment. Check that the restored database opens, migrations match the application version, and important queries return expected data.

Protect credentials and migrations

Keep database tokens in environment variables or a secret manager. Never embed them in JavaScript sent to the browser.

Run migrations through deployment automation. Store each migration in version control. Deploy the schema before deploying code that depends on new columns or indexes.

Use backward-compatible changes when the application has multiple running versions. Add a nullable column first, deploy code that writes it, backfill records, then add stricter constraints if the provider supports them safely.

Compare the Main Hosting Options

Use this table as a first filter, not as a replacement for load testing.

OptionConnection modelBest fitMain constraint
Turso/libSQLRemote client and hosted databaseServer apps, edge apps, multi-tenant systemsUsage quotas and provider-specific behavior
Cloudflare D1Worker bindingAPIs already running on Cloudflare WorkersWorker limits and no traditional database endpoint
Fly.io LiteFSLocal SQLite file with replicationTeams operating Fly MachinesYou manage storage, failover, and primary writes
Self-hosted SQLiteLocal file on one persistent hostInternal tools and low-traffic applicationsSingle-host availability and manual operations

The practical choice is usually clear after answering three questions:

  1. Where does the application already run?
  2. How many writes happen during peak periods?
  3. What recovery time and recovery point can the business accept?

Choose Turso when you want a hosted SQLite-compatible service without building the database layer. Choose D1 when Workers are already your application runtime. Choose LiteFS when you want SQLite on Fly Machines and can operate the supporting infrastructure.

Avoid Common Online SQLite Mistakes

Several deployment errors appear repeatedly.

Putting the database on ephemeral storage loses data when the instance is replaced. Attach persistent storage or use a managed provider.

Opening one connection per request without limits can exhaust runtime resources. Use the provider’s recommended client pattern and avoid creating unnecessary clients.

Assuming replicas accept writes can create conflicts or failed transactions. Confirm the provider’s write model and route writes to the supported authority.

Using long transactions increases lock contention. Keep the write section small and move slow work outside the transaction.

Skipping restore tests creates false confidence. A successful backup job doesn’t prove that your application can recover.

Comparing only monthly prices hides usage charges. Check storage, reads, writes, transfer, database counts, machine resources, and backup retention.

Provider features and pricing change. Recheck quotas, recovery windows, connection rules, and plan terms before moving a production workload.

Final Thoughts

You can host SQLite online without turning a small application into a database administration project. Start with the runtime, match the provider to your access pattern, and keep the database design within SQLite’s write model.

Turso and D1 reduce infrastructure work. LiteFS gives you more control on Fly.io. None of these options provides unlimited concurrent writes or removes the need for backups, migrations, and restore testing.

The safest deployment is the one with a clear write authority, short transactions, protected credentials, tested recovery, and limits that match your real workload.