Convex schemas, queries, mutations, actions, auth, migrations and components. Use when designing a Convex schema, writing Convex functions, setting up Convex auth, or migrating Convex data.
70
88%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Project-specific schema, functions, and deployment details: .opencastle/stack/database-config.md.
Official docs: https://docs.convex.dev/
Exceeding one of these fails the transaction, so design against them rather than discovering them:
| Limit | Value |
|---|---|
| Query/mutation execution time | 1 second (your code only, excludes DB operations) |
| Action execution time | 10 minutes |
| Data read / written | 16 MiB each |
| Documents scanned | 32,000 — includes documents .filter() discards |
| Index ranges read | 4,096 (each db.get and db.query counts) |
| Documents written | 16,000 |
| Function return value | 16 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.
Functions
query/mutation/action. Internal: internalQuery/internalMutation/internalAction. All from ./_generated/server.returns validator; use returns: v.null() when the function returns nothing (JS implicitly returns null).api.file.fn, internal.file.fn from ./_generated/api) to ctx.runQuery/runMutation/runAction — never the function itself.Queries
.filter(). Convex's .filter() performs the same as filtering in JS — neither pushes the predicate to storage. Only .withIndex()/.withSearchIndex() reduce documents scanned..delete(): collect results, then ctx.db.delete(row._id) per row..unique() for single-document reads.Mutations
ctx.db.patch() — an unchanged write still costs invalidation, replication, and trigger execution.Actions
ctx.db does not exist in actions — use ctx.runQuery/ctx.runMutation."use node"; at the top.Schema
["team", "user"] → by_team_and_user. Index fields must be queried in definition order._id or _creationTime — they are automatic system fields.by_team_and_user also serves by_team queries).v.null(), never v.undefined() — undefined is not a valid Convex value.Components
ctx.auth or process.env. Resolve both in the app and pass values across.v.string(), not v.id("parentTable").query/mutation/action from the component's own ./_generated/server.Environment
npx convex env set; read them with process.env in actions only.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.
| Step | Checkpoint |
|---|---|
| Schema change | npx convex dev starts without errors |
| Breaking change | checklist completed |
| Auth function | ctx.auth.getUserIdentity() non-null in test |
| Deploy | Smoke check passes; no npx convex insights regressions |
| Component | npx convex codegen succeeds |
monkilabs/opencastle
3942f46
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.