Blyp Docs

Database

Use database mode when Blyp cannot safely rely on local file persistence, especially in serverless or short-lived runtimes.

In this mode, Blyp replaces file logging as the primary persistence layer and writes normalized log rows into your application database. Connectors such as Better Stack, PostHog, Sentry, Databuddy, and OTLP still work independently.

Why the schema matters

Database mode is not just a config flag. It depends on a specific schema contract.

If the table, model, columns, indexes, or adapter wiring do not match what Blyp expects, database logging can become partially broken or fully unusable. Typical failure modes include:

Schema is required: Treat the generated Blyp schema as a compatibility contract. If you rename fields, remove indexes, or point the adapter at the wrong model or table, Blyp database logging may stop working correctly.

Supported setups

Required setup sequence

  1. Choose your adapter: Prisma or Drizzle.
  2. Choose your dialect: Postgres or MySQL.
  3. Create the required Blyp schema contract.
  4. Run migrations so the database actually matches that contract.
  5. Wire blyp.config.ts to the correct adapter runtime object.
  6. Run blyp db:generate if you are using Prisma.
  7. Emit a test log and confirm the row is inserted.

Required storage contract

The current CLI-generated contract is:

For the full column and index contract, see Schema Contract.

Adapter guides

blyp.config.ts requirement

Database mode requires an executable config file such as blyp.config.ts, blyp.config.mts, blyp.config.js, or blyp.config.cjs.

blyp.config.json is not enough because Prisma and Drizzle adapters are runtime objects, not plain JSON values.

Prisma example

import { PrismaClient } from "@prisma/client";
import { createPrismaDatabaseAdapter } from "@blyp/core/database";

const prisma = new PrismaClient();

export default {
  destination: "database",
  database: {
    dialect: "postgres",
    adapter: createPrismaDatabaseAdapter({
      client: prisma,
      model: "blypLog",
    }),
  },
};

Drizzle example

import { createDrizzleDatabaseAdapter } from "@blyp/core/database";
import { db } from "./db";
import { blypLogs } from "./db/schema/blyp";

export default {
  destination: "database",
  database: {
    dialect: "mysql",
    adapter: createDrizzleDatabaseAdapter({
      db,
      table: blypLogs,
    }),
  },
};

Delivery behavior

Database delivery supports immediate writes and batched writes.

Default values:

export default {
  destination: "database",
  database: {
    dialect: "postgres",
    adapter,
    delivery: {
      strategy: "batch",
      batchSize: 50,
      flushIntervalMs: 1000,
    },
  },
};

Flushing and shutdown

All Blyp loggers expose:

await logger.flush();
await logger.shutdown();

Promise-based and hook-driven integrations such as Elysia, Hono, Next.js, React Router, Astro, Nitro, Nuxt, SolidStart, SvelteKit, and TanStack Start flush database writes before the request finishes.

For callback-style servers such as Express, Fastify, and NestJS, call await logger.flush() at your own boundary when you need a hard durability point.

CLI workflow

The recommended guided flow is:

blyp db:init
blyp db:migrate
blyp db:generate

db:generate is Prisma-only.

Without a global install:

bunx @blyp/cli db:init
bunx @blyp/cli db:migrate
bunx @blyp/cli db:generate

The detailed command behavior is documented in Migrations.

traceId in database rows

As of @blyp/[email protected], request trace IDs are persisted in database records. Use this together with Request Tracing when you want request logs, browser logs, AI traces, connector-forwarded logs, and database rows to share the same correlation ID.