Configuration

Tuning is optional. Defaults work without any configuration; knobs exist for schemas that need different safety boundaries or cost assumptions.

Generator configuration

generator sql {
  provider   = "prisma-sql-generator"
  dialect    = "postgres"
  output     = "./generated/sql"
  skipInvalid = "true"
}
FieldDefaultDescription
providerrequiredUse prisma-sql-generator
dialectinferred when possiblepostgres or sqlite
output./generated/sqlGenerated SQL client output path
skipInvalidfalseSkip invalid @optimize directives instead of failing generation

Extension config

Pass limits and/or strategy directly to speedExtension. Both accept partial objects.

const db = prisma.$extends(
  speedExtension({
    postgres: sql,
    limits: {
      MAX_INCLUDES_PER_LEVEL: 20,
      MAX_INCLUDE_DEPTH: 8,
    },
    strategy: {
      defaultFanOut: 5,
      roundtripRowEquivalent: 40,
    },
  }),
)

Programmatic API

import {
  setLimits, getLimits, resetLimits,
  setStrategyConfig, getStrategyConfig,
  rebuildQueryCache,
} from 'prisma-sql'

setLimits({ MAX_INCLUDES_PER_LEVEL: 25 })
rebuildQueryCache()   // required after changing QUERY_CACHE_SIZE
setStrategyConfig({ correlatedBoundedFactor: 0.3 })
resetLimits()

Query builder limits

KeyDefaultDescription
MAX_INCLUDE_DEPTH5Max depth of nested include/select relations
MAX_INCLUDES_PER_LEVEL10Max relations included at one nesting level
MAX_TOTAL_SUBQUERIES100Total correlated subqueries allowed across the tree
MAX_SELF_REFERENTIAL_DEPTH2Max times a model can appear in its own include chain
MAX_QUERY_DEPTH50Max nesting depth for WHERE clauses
MAX_NOT_DEPTH50Max nesting depth for NOT composition
MAX_HAVING_DEPTH50Max nesting depth for HAVING clauses
MAX_NESTED_JOIN_DEPTH10Max depth for join-based relation traversal
MAX_RELATION_ORDER_BY_DEPTH10Max depth for relation orderBy resolution
MAX_WHERE_IN_RECURSIVE_DEPTH10Max recursion depth for where-in segment resolution
MAX_ARRAY_SIZE10000Max elements in array params such as in / hasSome
MAX_STRING_LENGTH10000Max string length for LIKE and JSON string operators
MAX_LIMIT_OFFSET2147483647PostgreSQL engine limit for LIMIT / OFFSET
MIN_NEGATIVE_TAKE-10000Minimum allowed negative take value
MAX_ALIAS_COUNTER_THRESHOLD1000Safety threshold before alias counter overflow
QUERY_CACHE_SIZE1000Max entries in the SQL query cache (call rebuildQueryCache after changing)
STMT_CACHE_SIZE1000Max entries in the SQLite prepared statement cache per client

Strategy cost-model parameters

These control how the planner chooses between query strategies.

KeyDefaultDescription
roundtripRowEquivalent73Cost in row-equivalents of one extra database roundtrip. Lower favors multi-roundtrip strategies.
jsonRowFactor1.5Multiplier for JSON aggregation overhead per row
correlatedBoundedFactor0.5Cost factor for correlated subqueries when the child has LIMIT
correlatedUnboundedFactor3.0Cost factor for correlated subqueries when the child is unbounded
correlatedWherePenalty3.0Extra cost when a child relation has where inside a correlated subquery
defaultFanOut10Assumed average children per parent without stats
defaultParentCount50Assumed parent row count when take is not specified
dynamicTakeEstimate10Assumed take value when actual value is a runtime parameter
singleParentMaxFlatJoinDepth2Max include depth allowing flat-join for findFirst/findUnique
minStatsCoverage0.1Minimum relation stats coverage to trust collected data
largeChildTableRows100000Child table threshold for the large to-many include guard
smallParentCountThreshold1000Parent estimate threshold for the large to-many include guard

Tuning examples

// low-latency local database
speedExtension({ postgres: sql, strategy: { roundtripRowEquivalent: 20 } })

// remote database with high latency
speedExtension({ postgres: sql, strategy: { roundtripRowEquivalent: 200 } })

// large child tables that are well indexed
speedExtension({ postgres: sql, strategy: { largeChildTableRows: 500000 } })