Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>Plinth — Index Advisor for Prisma, Drizzle and TypeORMNew to Visual Studio Code? Get it now.
Plinth — Index Advisor for Prisma, Drizzle and TypeORM

Plinth — Index Advisor for Prisma, Drizzle and TypeORM

Plinth

|
1 install
| (0) | Free
Catch the missing index in your editor, not in your incident channel. Flags Prisma, Drizzle and TypeORM queries that slow down at production scale on PostgreSQL and MySQL, and writes the exact migration to fix them.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Plinth for VS Code

Catch the missing index in your editor, not in your incident channel.

Plinth reads your ORM queries as you write them, finds the ones that will slow down at production scale, and writes the exact change to fix them.

PostgreSQL MySQL
Prisma ✓ ✓
Drizzle ✓ ✓
TypeORM ✓ ✓

What it catches

  • Unindexed filters and sorts: a filter plus sort with no composite index behind it.
  • Foreign keys without an index: PostgreSQL never creates them; MySQL does only for real constraints.
  • Unbounded list queries: no take / limit, so the result grows with the table.
  • Queries in loops: one round trip per item (it knows Prisma batches findUnique).

The fix, in your ORM's own terms

ORM Schema change Migration
Prisma @@index([status, createdAt]) in the model prisma/migrations/<timestamp>_add_…_index/migration.sql
Drizzle index("…").on(t.status, t.createdAt) in the table run drizzle-kit generate
TypeORM @Index("…", ["status", "createdAt"]) on the entity src/migrations/<timestamp>-Add…Index.ts (your migrations path)

Index names are explicit and identical in the schema and the SQL, so your migration tool reports no drift. On PostgreSQL the SQL uses CREATE INDEX CONCURRENTLY; on MySQL, online DDL (ALGORITHM=INPLACE LOCK=NONE). TypeORM migrations build concurrently only when your DataSource sets migrationsTransactionMode: "each", because CONCURRENTLY cannot run inside a transaction.

Confidence and table sizes

Static code can't see how big your tables are, so every finding carries a confidence level. Raise it by declaring rough sizes in plinth.config.json next to your package.json. Keys can be model, entity or table names:

{ "tables": { "orders": { "rows": 5000000, "distinct": { "status": 4 } } } }

Or run Plinth: Copy table-size query and execute it on a replica or staging database. It reads planner statistics only (PostgreSQL pg_class/pg_stats, MySQL information_schema), never row contents, and returns that JSON ready to paste. Tables declared under 10k rows are left alone.

Plinth reads the database from your ORM config (Prisma provider, Drizzle pgTable/mysqlTable, TypeORM DataSource type). If it can't, set "dialect": "postgresql" or "mysql" in plinth.config.json.

Silencing a finding

// plinth-ignore-next-line unbounded-query
const all = await prisma.country.findMany();

Use Ignore … here from the lightbulb, or // plinth-ignore-file at the top of a file.

Settings

Setting Default Description
plinth.enable true Analyze as you type
plinth.schemaPath auto Prisma only: schema.prisma or a prisma/schema/ folder
plinth.minConfidence low Hide findings below this confidence

Privacy

Everything runs locally. Your code and schema never leave your machine. Plinth collects no telemetry.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft