CtrlK
BlogDocsLog inGet started
Tessl Logo

convex-database

Convex reactive database patterns, schema design, real-time queries, mutations, actions, authentication, migrations, performance optimization, and component creation. Use when designing Convex schemas, writing queries/mutations, managing the Convex backend, setting up auth, migrating data, optimizing performance, or building Convex components.

73

Quality

91%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Low

Low-risk findings worth noting

SKILL.md
Quality
Evals
Security

Convex Database

Project-specific schema, functions, and deployment details: database-config.md. Official docs: https://docs.convex.dev/

Hard limits per transaction

Exceeding one of these fails the transaction, so design against them rather than discovering them:

LimitValue
Query/mutation execution time1 second (your code only, excludes DB operations)
Action execution time10 minutes
Data read / written16 MiB each
Documents scanned32,000 — includes documents .filter() discards
Index ranges read4,096 (each db.get and db.query counts)
Documents written16,000
Function return value16 MiB

Batch anything larger into a cursor-based self-scheduling internalMutation: paginate({ cursor, numItems }), then ctx.scheduler.runAfter(0, internal.x.batch, { cursor: result.continueCursor }) while !result.isDone — or use the migrations component.

Rules That Are Easy To Get Wrong

Functions

  • Public: query/mutation/action. Internal: internalQuery/internalMutation/internalAction. All from ./_generated/server.
  • Always set a returns validator; use returns: v.null() when the function returns nothing (JS implicitly returns null).
  • Pass function references (api.file.fn, internal.file.fn from ./_generated/api) to ctx.runQuery/runMutation/runAction — never the function itself.

Queries

  • Do not use .filter(). Convex's .filter() performs the same as filtering in JS — neither pushes the predicate to storage. Only .withIndex()/.withSearchIndex() reduce documents scanned.
  • Queries have no .delete(): collect results, then ctx.db.delete(row._id) per row.
  • .unique() for single-document reads.

Mutations

  • Skip no-op writes: compare before ctx.db.patch() — an unchanged write still costs invalidation, replication, and trigger execution.
  • Mutations are ACID transactional; use actions for external API calls and side effects.
  • Breaking schema changes need widen-migrate-narrow across two deploys (widen, migrate, then narrow).

Actions

  • ctx.db does not exist in actions — use ctx.runQuery/ctx.runMutation.
  • Files containing actions that use Node.js built-in modules need "use node"; at the top.

Schema

  • Index names must list every field: ["team", "user"]by_team_and_user. Index fields must be queried in definition order.
  • Never define _id or _creationTime — they are automatic system fields.
  • Prefer one compound index over redundant single-field indexes (by_team_and_user also serves by_team queries).
  • Use v.null(), never v.undefined()undefined is not a valid Convex value.

Components

  • Components cannot access ctx.auth or process.env. Resolve both in the app and pass values across.
  • Parent-app IDs cross the boundary as v.string(), not v.id("parentTable").
  • Import query/mutation/action from the component's own ./_generated/server.

Environment

  • Set Convex env vars in the dashboard or with npx convex env set; read them with process.env in actions only.

Deploy Loop

npx convex dev (long-running watcher, interactive on first run — ask the user to run it) → verify → npx convex deploy. If a deploy goes wrong, roll back by npx convex import of the last good export, fix locally, re-deploy.

StepCheckpoint
Schema changenpx convex dev starts without errors
Breaking changechecklist completed
Auth functionctx.auth.getUserIdentity() non-null in test
DeploySmoke check passes; no npx convex insights regressions
Componentnpx convex codegen succeeds
Repository
monkilabs/opencastle
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.