Sota databases
State-of-the-art database engineering rules (2026) for designing, building, and auditing data layers. Covers engine selection, schema modeling, migrations, query and index craft, transactions and concurrency, reliability and scale, security, and vector/AI workloads. Use when designing a new data layer, writing or reviewing schemas/migrations/queries, debugging slow or contended database workloads, or auditing an existing database for correctness, performance, and security. Not for ETL or streaming data pipelines — use sota-data-engineering. Trigger keywords: database, SQL, Postgres, schema, migration, index, query, ORM, transaction, NoSQL, Redis, vector DB, pgvector, replication, partitioning, connection pool, RLS, EXPLAIN, deadlock, sharding, caching, SurrealDB, SurrealQL, Qdrant, multi-model, graph database.From its SKILL.md
npx -y skills add martinholovsky/SOTA-skills --skill sota-databasesAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 12 stars12 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
8.2 KB, ~1.8k tokens by cl100k_base, as published. Nobody here has run it
SOTA Databases
Expert-level rules for the full lifecycle of a data layer: choosing an engine, modeling data, evolving schemas safely, writing efficient queries, handling concurrency, operating reliably at scale, securing data, and supporting vector/AI workloads. Postgres is the reference engine; rules call out where other systems (MySQL, Redis, document/columnar/vector stores) differ.
This skill operates in two modes. Determine the mode from the user's intent,
then load the relevant rules/ files per the index below. Do not load all
files preemptively — pick by task.
BUILD mode
Use when designing or implementing: new schemas, migrations, queries, ORM layers, caching, job queues, or database infrastructure.
- Engine and model first. Read
rules/01-choosing-and-modeling.mdbefore writing any DDL. Default to Postgres unless a rule there says otherwise. - Every schema change is a migration. Never hand the user raw DDL to run
ad hoc; produce migration files following
rules/02-schema-migrations.md(expand/contract, lock-aware, reversible-or-documented). - Design indexes with the queries, not after. When writing a query that
will run in production, state which index serves it. Follow
rules/03-queries-and-indexes.md. - State the concurrency story. For any write path: idempotency, isolation
level, locking strategy, retry behavior (
rules/04-transactions-concurrency.md). - Operational defaults are part of the design. Pooling, backups,
monitoring hooks, and retention are not "later" items
(
rules/05-reliability-and-scale.md,rules/06-security-and-compliance.md). - Prefer boring, well-trodden patterns. Novelty in the data layer is a cost, not a feature.
AUDIT mode
Use when reviewing an existing schema, migration set, query workload, ORM usage, or database configuration.
Procedure:
- Inventory: engine + version, schema (tables, indexes, constraints), migration tooling, ORM, pooling setup, backup/replication config.
- Load the rules files matching what exists (e.g., no vectors → skip 07).
- Check each rule; report deviations as findings. Verify claims against the actual schema/queries — never report a finding you have not confirmed in the code or DDL.
Severity conventions:
- CRITICAL — data loss, corruption, or breach is likely or already possible: untested/missing backups, SQL injection, unconstrained deletes, missing FK causing orphaned money/auth rows, RLS bypass, plaintext secrets.
- HIGH — production incident waiting to happen: non-CONCURRENT index on a hot table, table rewrite migration without expand/contract, missing unique constraint under concurrent writes, unbounded long transactions, no lock_timeout in migrations, offset pagination on large tables in hot paths.
- MEDIUM — correctness or performance debt: N+1 queries, SELECT *, missing composite index for a known query, soft delete without partial indexes, natural primary keys, missing updated_at/audit trail where required.
- LOW — hygiene: naming inconsistencies, missing comments on cryptic columns, redundant indexes, suboptimal types (e.g., varchar(255) cargo cult).
Finding format (one per finding):
[SEVERITY] <short title>
Where: <file:line | table/column | migration id>
Rule: <rules file + rule heading>
Evidence: <the offending DDL/SQL/code, quoted>
Impact: <what breaks, when, under what load>
Fix: <concrete change — exact SQL/DDL/code where possible>
Order findings by severity. End with a summary table: count per severity, and the top 3 fixes by risk-reduction-per-effort.
Rules index
| File | Read this when... |
|---|---|
rules/01-choosing-and-modeling.md | Picking an engine (SQL vs NoSQL/KV/columnar/time-series/vector); designing tables; deciding normalization, JSONB usage, primary keys, soft deletes, audit/history tables, or multi-tenancy. |
rules/02-schema-migrations.md | Writing or reviewing any migration; altering hot tables; planning zero-downtime schema changes; backfills; setting up migration tooling or testing. |
rules/03-queries-and-indexes.md | Writing/reviewing queries or ORM code; reading EXPLAIN ANALYZE; choosing index types or composite column order; pagination; N+1 suspicion; CTEs and window functions. |
rules/04-transactions-concurrency.md | Anything with concurrent writes: isolation levels, locking (FOR UPDATE, SKIP LOCKED, advisory), job queues, idempotency, deadlocks, long transactions, connection pooling. |
rules/05-reliability-and-scale.md | Backups/PITR, replication and read replicas, partitioning, vacuum/bloat, monitoring, capacity planning, sharding decisions, Redis caching patterns and distributed locks. |
rules/06-security-and-compliance.md | DB roles and grants, RLS, encryption at rest/in transit, SQL injection surface, PII columns, data retention and GDPR-style deletion. |
rules/07-vector-and-ai.md | Embeddings, semantic/hybrid search, pgvector vs dedicated vector DBs (incl. Qdrant exposure hardening), embedding model versioning and re-indexing. |
rules/08-surrealdb-multimodel.md | Building on or auditing SurrealDB: DEFINE ACCESS auth, system users and least privilege, parameterized SurrealQL, SCHEMAFULL + PERMISSIONS, capability flags, indexes, multi-model (embed/reference/graph edges), backups. |
Top 10 non-negotiables
Violations of these are at minimum HIGH severity in AUDIT mode and must not be introduced in BUILD mode.
- Postgres until proven otherwise. A second datastore needs a written reason that Postgres (with JSONB, partitioning, pgvector, LISTEN/NOTIFY) cannot meet — not a vibe.
- No natural primary keys. Surrogate keys only:
bigint GENERATED ALWAYS AS IDENTITYinternally, UUIDv7 when IDs are exposed or generated client-side. Never email, SSN, slug, or composite business fields as PK. - Expand/contract, always. No migration may break the currently deployed application version. Add → migrate code → backfill → contract, as separate deploys.
- Lock-aware DDL on hot tables.
CREATE INDEX CONCURRENTLY,SET lock_timeout, batched backfills,NOT VALID+VALIDATE CONSTRAINT. Never an unboundedALTER TABLErewrite or blocking index build on a table with traffic. - Constraints in the database, not only the app. Uniqueness, foreign keys, NOT NULL, and CHECK live in the schema. Application-level "validation only" uniqueness is a race condition, not a constraint.
- Every production query has a known index. If you cannot name the index
a query uses (or justify a seq scan), the query is not done. Keyset
pagination, no
SELECT *, no N+1. - Idempotent writes on every retryable path. Unique keys, upserts, or idempotency keys — any write that a client, queue, or webhook may retry must be safe to execute twice.
- A backup that has not been restored is not a backup. PITR configured, restores rehearsed, RPO/RTO stated. Replication is not backup.
- Least privilege at the database. The app role owns no schema, cannot DROP, and cannot read tables it does not use. Migrations run as a separate role. No superuser connection strings in app config.
- Transactions are short. No network calls, no user waits, no batch loops inside a transaction. Long transactions cause bloat, lock queues, and replication lag — treat any transaction over ~1s as a design bug.
What ships with it: 8 files
109.3 KB alongside SKILL.md
rules/
- 01-choosing-and-modeling.md13.6 KB
- 02-schema-migrations.md13.9 KB
- 03-queries-and-indexes.md12.0 KB
- 04-transactions-concurrency.md13.3 KB
- 05-reliability-and-scale.md15.0 KB
- 06-security-and-compliance.md12.8 KB
- 07-vector-and-ai.md14.5 KB
- 08-surrealdb-multimodel.md14.2 KB
Gives 1 of the 12 instructions most databases sql skills give in ~1.8k tokens
Counted across 609 of the 712 authors here whose files we hold, read 2026-09-06
- Index all foreign key columnsin 26 of 609
- Use cursor pagination instead of offsetin 25 of 609, across 20 files
- Use timestamptz for timestampsin 21 of 609
- Specify columns instead of using select starin 20 of 609, across 10 files
- Use parameterized queries for all database interactionsin 20 of 609, across 19 files
- Use Enum for categorical datain 17 of 609, across 7 files
- Order by frequently filtered columnsin 17 of 609, across 7 files
- Batch data insertsin 17 of 609, across 7 files
- Use expand-contract pattern for schema changeshere, and in 17 of 609
- Use materialized views for real-time aggregationsin 16 of 609, across 6 files
- Partition tables by timein 16 of 609, across 6 files
- Use smallest appropriate data typesin 16 of 609, across 6 files
Said here and by no other author read
- Default to Postgres unless a specific rule dictates otherwise
- Produce migration files instead of raw DDL
- State which index serves every production query
- Define concurrency strategies for every write path
- Include operational defaults in the initial design
- Prefer boring and well-trodden patterns
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.