What Database Options Does OpenSEO Support? D1 vs PostgreSQL Explained

OpenSEO supports Cloudflare D1 (SQLite) for zero-config development and PostgreSQL for production workloads, switchable via the DATABASE_PROVIDER environment variable.

The every-app/open-seo repository implements a provider-aware data layer that abstracts database specifics behind a unified client interface. By supporting both serverless SQLite via Cloudflare D1 and full PostgreSQL instances, OpenSEO lets developers start on a free tier and scale to production without refactoring query logic. Understanding these OpenSEO database options allows you to choose the right backend for your traffic and complexity requirements.

Supported Database Providers

Cloudflare D1 (SQLite) — The Default

D1 is the default provider, activated automatically when no explicit configuration is present. It stores data in a lightweight SQLite database managed by Cloudflare’s D1 service, which runs on their free tier. The default selection logic lives in src/db/provider.ts, where the system initializes the D1 driver unless DATABASE_PROVIDER=postgres is detected.

PostgreSQL — The Production Alternative

For applications requiring complex transactions, advanced indexing, or higher concurrency, OpenSEO supports PostgreSQL via the postgres provider. Enabling this requires setting the DATABASE_PROVIDER environment variable and configuring a Hyperdrive binding (or a local connection string for development). The provider logic in src/db/provider.ts exposes getPostgresConnectionString() for scripts that need direct database access.

How the Provider Abstraction Works

OpenSEO centralizes database access through a single export in src/db/index.ts. This module resolves the active provider at runtime by checking the environment variable:

// src/db/index.ts
export const db = (getDatabaseProvider() === "postgres"
  ? pgDb
  : d1Db) as unknown as typeof d1Db;

This architecture ensures that application code remains database-agnostic. Whether you import db in an API route or a background job, the underlying engine (D1 or Postgres) is transparent to the consumer. TypeScript definitions in src/env.d.ts enforce type safety by restricting DATABASE_PROVIDER to the union type "d1" | "postgres".

Configuring Your Database Environment

Control the active database by setting environment variables in your project root:

Using D1 (Development):


# .env

DATABASE_PROVIDER=d1

Using PostgreSQL (Production):


# .env.production

DATABASE_PROVIDER=postgres

Once configured, import the unified client anywhere in your server code:

// Any server function
import { db } from "@/db";

export async function getProjects() {
  // Identical syntax works for both D1 and Postgres
  return await db.select().from(projects).all();
}

If you need the raw Postgres connection string for external tooling or custom migrations, use the provider-specific helper:

import { getPostgresConnectionString } from "@/db/provider";

const connStr = getPostgresConnectionString(); 
// Throws if DATABASE_PROVIDER is not "postgres"

Summary

  • Two supported backends: Cloudflare D1 (SQLite) as the zero-config default and PostgreSQL as the opt-in production database.
  • Environment-driven switching: Set DATABASE_PROVIDER to "d1" or "postgres" in your environment variables; src/db/provider.ts handles the resolution.
  • Database-agnostic queries: Import db from src/db/index.ts to write code that works regardless of the underlying engine.
  • Type safety: src/env.d.ts ensures compile-time checking of the provider selection.
  • Drizzle ORM integration: Separate configuration files (drizzle.config.ts and drizzle-pg.config.ts) manage schema migrations for each dialect.

Frequently Asked Questions

Is Cloudflare D1 free to use with OpenSEO?

Yes. D1 is the default provider in src/db/provider.ts and operates on Cloudflare’s free tier, making it ideal for prototyping and small-scale deployments without incurring database hosting costs.

How do I switch from D1 to PostgreSQL in OpenSEO?

Set DATABASE_PROVIDER=postgres in your environment variables and ensure you have a Hyperdrive binding or valid connection string configured. No application code changes are required because the unified db export in src/db/index.ts automatically switches the underlying driver based on the provider setting.

What is Hyperdrive and why does PostgreSQL require it?

Hyperdrive is Cloudflare’s connection pooling service that optimizes latency and throughput to external databases. When using the postgres provider in production, OpenSEO expects a Hyperdrive binding to manage connections efficiently, though local development can use standard connection strings defined in your environment.

Can I use both databases simultaneously in the same OpenSEO deployment?

No. The architecture uses a single provider resolution at runtime in src/db/index.ts. While the codebase is structured to support either provider, it does not support querying both D1 and Postgres in the same runtime instance; you must choose one provider via the DATABASE_PROVIDER variable.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →