ParqueDB
Deployment

Configuration

Complete reference for all ParqueDB configuration options across Node.js, Cloudflare Workers, and browser environments.

Complete reference for all ParqueDB configuration options across different deployment environments.

Table of Contents


Overview

ParqueDB configuration varies based on your deployment environment:

EnvironmentConfiguration Method
Node.jsConstructor options + environment variables
Cloudflare Workerswrangler.jsonc + environment variables
BrowserConstructor options only

ParqueDB Options

Constructor Options

import { ParqueDB, FsBackend } from 'parquedb'

const db = new ParqueDB({
  // Required: Storage backend
  storage: new FsBackend('./data'),

  // Optional: Schema definition
  schema: {
    Post: {
      $ns: 'posts',
      title: 'string!',
      content: 'markdown!',
      status: 'enum(draft,published,archived) = draft',
      author: '-> User.posts'
    },
    User: {
      $ns: 'users',
      name: 'string!',
      email: { type: 'email!', index: 'unique' },
      posts: '<- Post.author[]'
    }
  },

  // Optional: Default actor for audit trails
  defaultActor: 'system/anonymous',

  // Optional: Enable event sourcing
  eventSourcing: true,

  // Optional: Enable time-travel queries
  timeTravel: true
})

Option Reference

OptionTypeDefaultDescription
storageStorageBackendRequiredStorage backend instance
schemaRecord<string, SchemaDefinition>undefinedSchema definitions for validation
defaultActorstring'system/anonymous'Default actor ID for operations
eventSourcingbooleanfalseEnable event log for CDC
timeTravelbooleanfalseEnable point-in-time queries

Storage Backends

MemoryBackend

In-memory storage for testing and development.

import { MemoryBackend } from 'parquedb'

const storage = new MemoryBackend()

// Data is lost when process exits
const db = new ParqueDB({ storage })
FeatureSupport
PersistenceNo
Atomic writesYes
Range readsYes
Best forTesting, development

FsBackend

Node.js filesystem storage.

import { FsBackend } from 'parquedb'

const storage = new FsBackend('./data')

// Or with absolute path
const storage = new FsBackend('/var/lib/parquedb/data')
FeatureSupport
PersistenceYes
Atomic writesYes (temp file + rename)
Range readsYes
Best forNode.js standalone deployments

Security: FsBackend includes path traversal protection. Paths cannot escape the root directory.

R2Backend

Cloudflare R2 object storage.

import { R2Backend } from 'parquedb'

// In a Cloudflare Worker
const storage = new R2Backend(env.BUCKET, {
  prefix: 'parquedb/'  // Optional: key prefix
})
OptionTypeDefaultDescription
prefixstring''Prefix for all R2 keys
FeatureSupport
PersistenceYes
Atomic writesYes
Range readsYes
Multipart uploadYes
Best forCloudflare Workers production

DOSqliteBackend

Cloudflare Durable Object SQLite storage for metadata.

import { DOSqliteBackend } from 'parquedb'

// In a Durable Object
const storage = new DOSqliteBackend(this.ctx.storage.sql, {
  prefix: ''  // Optional: key prefix
})
OptionTypeDefaultDescription
prefixstring''Prefix for all keys
FeatureSupport
PersistenceYes (DO storage)
ACID transactionsYes
Max blob size2MB
Best forDO metadata, small datasets

Cloudflare Worker Configuration

wrangler.jsonc Reference

{
  // =============================================================================
  // Basic Settings
  // =============================================================================

  // JSON schema for IDE autocomplete
  "$schema": "node_modules/wrangler/config-schema.json",

  // Worker name (used in URLs and dashboard)
  "name": "my-parquedb-api",

  // Entry point
  "main": "src/index.ts",

  // Cloudflare runtime version
  "compatibility_date": "2026-01-30",

  // Enable Node.js APIs
  "compatibility_flags": ["nodejs_compat"],

  // =============================================================================
  // Routes (Optional)
  // =============================================================================

  // Custom domain routing
  "routes": [
    {
      "pattern": "api.example.com/*",
      "zone_name": "example.com"
    }
  ],

  // Or use workers.dev subdomain (default)
  // Worker available at: my-parquedb-api.youraccount.workers.dev

  // =============================================================================
  // Durable Objects
  // =============================================================================

  "durable_objects": {
    "bindings": [
      {
        // Binding name (used in code as env.PARQUEDB)
        "name": "PARQUEDB",
        // Class name (must be exported from entry point)
        "class_name": "ParqueDBDO"
      }
    ]
  },

  // DO migrations - required for new DOs
  "migrations": [
    {
      "tag": "v1",
      "new_sqlite_classes": ["ParqueDBDO"]
    }
  ],

  // =============================================================================
  // R2 Buckets
  // =============================================================================

  "r2_buckets": [
    {
      // Binding name (used in code as env.BUCKET)
      "binding": "BUCKET",
      // Production bucket name
      "bucket_name": "my-parquedb-data",
      // Preview bucket for wrangler dev
      "preview_bucket_name": "my-parquedb-data-preview"
    },
    {
      // Optional: CDN bucket with public access
      "binding": "CDN_BUCKET",
      "bucket_name": "my-parquedb-cdn"
    }
  ],

  // =============================================================================
  // Workers AI (Optional)
  // =============================================================================

  "ai": {
    "binding": "AI"
  },

  // =============================================================================
  // Environment Variables
  // =============================================================================

  "vars": {
    "ENVIRONMENT": "development",
    "LOG_LEVEL": "info",

    // Cache configuration
    "CACHE_DATA_TTL": "60",
    "CACHE_METADATA_TTL": "300",
    "CACHE_BLOOM_TTL": "600",
    "CACHE_STALE_WHILE_REVALIDATE": "true",

    // CDN URL for edge caching
    "CDN_R2_DEV_URL": "https://cdn.example.com/parquedb"
  },

  // =============================================================================
  // Development Settings
  // =============================================================================

  "dev": {
    "port": 8787,
    "local_protocol": "http",
    "ip": "0.0.0.0"  // Listen on all interfaces
  },

  // =============================================================================
  // Build Configuration
  // =============================================================================

  "build": {
    "command": "npm run build",
    "watch_dir": "src"
  },

  // =============================================================================
  // Limits
  // =============================================================================

  "limits": {
    "cpu_ms": 50  // Max CPU time per request (ms)
  },

  // =============================================================================
  // Environment Overrides
  // =============================================================================

  "env": {
    "production": {
      "vars": {
        "ENVIRONMENT": "production",
        "LOG_LEVEL": "warn"
      },
      "r2_buckets": [
        {
          "binding": "BUCKET",
          "bucket_name": "my-parquedb-data-prod"
        }
      ]
    },
    "staging": {
      "vars": {
        "ENVIRONMENT": "staging"
      },
      "r2_buckets": [
        {
          "binding": "BUCKET",
          "bucket_name": "my-parquedb-data-staging"
        }
      ]
    }
  }
}

wrangler.jsonc Options Reference

OptionTypeDescription
namestringWorker name
mainstringEntry point file
compatibility_datestringRuntime version (YYYY-MM-DD)
compatibility_flagsstring[]Feature flags
routesRoute[]Custom domain routing
durable_objectsobjectDO bindings
migrationsMigration[]DO migrations
r2_bucketsR2Binding[]R2 bucket bindings
aiobjectWorkers AI binding
varsRecord<string, string>Environment variables
devobjectDevelopment settings
buildobjectBuild configuration
limitsobjectResource limits
envobjectEnvironment-specific overrides

Cache Configuration

CacheConfig Options

import { CacheStrategy, DEFAULT_CACHE_CONFIG } from 'parquedb/worker'

interface CacheConfig {
  // TTL for Parquet data files (seconds)
  dataTtl: number

  // TTL for metadata/schema (seconds)
  metadataTtl: number

  // TTL for bloom filters (seconds)
  bloomTtl: number

  // Use stale-while-revalidate
  staleWhileRevalidate: boolean

  // Maximum size to cache (bytes, 0 = no limit)
  maxCacheSize?: number
}

Preset Configurations

import {
  DEFAULT_CACHE_CONFIG,
  READ_HEAVY_CACHE_CONFIG,
  WRITE_HEAVY_CACHE_CONFIG,
  NO_CACHE_CONFIG
} from 'parquedb/worker'
PresetData TTLMetadata TTLBloom TTLUse Case
DEFAULT_CACHE_CONFIG60s300s600sBalanced workloads
READ_HEAVY_CACHE_CONFIG300s900s1800sAnalytics, dashboards
WRITE_HEAVY_CACHE_CONFIG15s60s120sFrequently updated data
NO_CACHE_CONFIG000Development, debugging

Environment-Based Configuration

import { createCacheStrategy } from 'parquedb/worker'

// Reads from env vars:
// - CACHE_DATA_TTL
// - CACHE_METADATA_TTL
// - CACHE_BLOOM_TTL
// - CACHE_STALE_WHILE_REVALIDATE
const strategy = createCacheStrategy(env)

Custom Configuration

const customConfig: CacheConfig = {
  dataTtl: 120,          // 2 minutes
  metadataTtl: 600,      // 10 minutes
  bloomTtl: 1800,        // 30 minutes
  staleWhileRevalidate: true
}

const strategy = new CacheStrategy(customConfig)

Index Configuration

Secondary Index Types

ParqueDB supports multiple index types:

Index TypeUse CaseLookup Time
HashIndexExact equality (status = 'published')O(1)
SSTIndexRange queries (price >= 100)O(log n)
FTSIndexFull-text searchO(1) per term
BloomFilterNegative lookups (ID not exists)O(1)

Index Configuration

import { IndexManager, HashIndex, SSTIndex, FTSIndex } from 'parquedb'

// Hash index for equality lookups
const statusIndex = new HashIndex(storage, 'posts', 'status')
await statusIndex.build()

// SST index for range queries
const dateIndex = new SSTIndex(storage, 'posts', 'createdAt')
await dateIndex.build()

// Full-text search index
const ftsIndex = new FTSIndex(storage, 'posts', ['title', 'content'])
await ftsIndex.build()

Index Catalog

Indexes are tracked in {namespace}/indexes/_catalog.json:

{
  "indexes": [
    {
      "name": "status_hash",
      "type": "hash",
      "field": "status",
      "path": "posts/indexes/status_hash.idx",
      "createdAt": "2026-01-30T12:00:00Z"
    },
    {
      "name": "createdAt_sst",
      "type": "sst",
      "field": "createdAt",
      "path": "posts/indexes/createdAt_sst.sst",
      "createdAt": "2026-01-30T12:00:00Z"
    }
  ]
}

Query Options

FindOptions

interface FindOptions<T = unknown> {
  // Maximum results to return
  limit?: number

  // Number of results to skip (offset pagination)
  skip?: number

  // Cursor for cursor-based pagination
  cursor?: string

  // Sort specification
  sort?: Record<string, 1 | -1 | 'asc' | 'desc'>

  // Projection (fields to include/exclude)
  project?: Record<string, 0 | 1>

  // Index hint
  hint?: { index: string }

  // Include deleted entities
  includeDeleted?: boolean
}

Usage Examples

// Pagination with limit and cursor
const page1 = await db.Posts.find({}, { limit: 20 })
const page2 = await db.Posts.find({}, { limit: 20, cursor: page1.nextCursor })

// Sorting
const newest = await db.Posts.find({}, {
  sort: { createdAt: -1, title: 1 }
})

// Projection (include only specific fields)
const titles = await db.Posts.find({}, {
  project: { title: 1, status: 1 }
})

// Projection (exclude fields)
const noContent = await db.Posts.find({}, {
  project: { content: 0, rawHtml: 0 }
})

// Index hint
const byStatus = await db.Posts.find({ status: 'published' }, {
  hint: { index: 'status_hash' }
})

GetOptions

interface GetOptions {
  // Include deleted entities
  includeDeleted?: boolean

  // Populate relationships
  populate?: string[]
}

CreateOptions

interface CreateOptions {
  // Actor performing the operation (for audit)
  actor?: string

  // Skip schema validation
  skipValidation?: boolean
}

UpdateOptions

interface UpdateOptions {
  // Actor performing the operation
  actor?: string

  // Expected version for optimistic concurrency
  expectedVersion?: number

  // Create if not exists
  upsert?: boolean
}

DeleteOptions

interface DeleteOptions {
  // Actor performing the operation
  actor?: string

  // Hard delete (permanent, no soft delete)
  hard?: boolean

  // Expected version for optimistic concurrency
  expectedVersion?: number
}

Environment Variables

Node.js Environment Variables

VariableDefaultDescription
PORT3000HTTP server port
NODE_ENVdevelopmentEnvironment name
DATA_DIR./dataData directory path
LOG_LEVELinfoLogging level (debug, info, warn, error)

Cloudflare Worker Environment Variables

Set in wrangler.jsonc under vars:

VariableDefaultDescription
ENVIRONMENTdevelopmentEnvironment name
LOG_LEVELinfoLogging level
CACHE_DATA_TTL60Data cache TTL (seconds)
CACHE_METADATA_TTL300Metadata cache TTL (seconds)
CACHE_BLOOM_TTL600Bloom filter cache TTL (seconds)
CACHE_STALE_WHILE_REVALIDATEtrueEnable stale-while-revalidate
CDN_R2_DEV_URL-CDN URL for public R2 access

Secrets (Cloudflare)

Set via Wrangler CLI (not in config files):

# Set a secret
npx wrangler secret put AUTH_SECRET

# Set for specific environment
npx wrangler secret put AUTH_SECRET --env production

# Delete a secret
npx wrangler secret delete AUTH_SECRET
SecretDescription
AUTH_SECRETAuthentication secret for API tokens

Performance Tuning Options

Query Performance

// Enable query explain for debugging
const plan = await db.Posts.explain({ status: 'published' })
console.log(plan)
// {
//   usesIndex: true,
//   indexName: 'status_hash',
//   estimatedRows: 1000,
//   scanType: 'index_lookup'
// }

Memory Limits

For Cloudflare Workers, memory is limited to 128MB. For large queries:

// Use pagination
const allPosts: Post[] = []
let cursor: string | undefined

do {
  const result = await db.Posts.find({}, { limit: 100, cursor })
  allPosts.push(...result.items)
  cursor = result.nextCursor
} while (cursor)

// Use projection to reduce memory
const ids = await db.Posts.find({}, {
  project: { $id: 1 }
})

Worker CPU Limits

Default CPU limit is 50ms per request. For complex queries:

// Split into multiple requests
// Or increase limit in wrangler.jsonc:
{
  "limits": {
    "cpu_ms": 100  // Max 100ms CPU time
  }
}

Next Steps

On this page