Files
Eric Allam 9211032733 chore(database): drop unused TaskRun status composite index (#3743)
## Summary

Drops the `TaskRun_status_runtimeEnvironmentId_createdAt_id_idx` index
from the `TaskRun` table. After #3742 gated the legacy
`WAITING_FOR_DEPLOY` drain to V1-engine workers only, this index sees
zero scans on both writer and reader replicas. Removing it cuts index
maintenance on every `TaskRun` INSERT/UPDATE.

## Why

The index existed to support `WHERE status = X AND runtimeEnvironmentId
= Y` queries from `ExecuteTasksWaitingForDeployService`, which is
V1-only and no longer triggered on V2 deployments. A code grep across
`apps/webapp` and `internal-packages/run-engine` confirmed no V2
production query uses this access pattern — every other `status:` filter
on `TaskRun` is paired with `id`/`friendlyId`/`parentSpanId` and uses a
different index.

Dropping it also unlocks HOT updates on the dequeue path. The dequeue
`UPDATE` modifies `status` (`QUEUED` -> `DEQUEUED`), and `status` is the
leading column of this index — its presence blocked HOT eligibility for
every `TaskRun` UPDATE. With the index gone, dequeue UPDATEs can become
HOT, reducing WAL bytes and removing the B-tree page contention on this
index's right-edge leaves.

Uses `DROP INDEX CONCURRENTLY` to avoid blocking writes during the drop.

## Sequencing

Should only ship once #3742 has soaked long enough to confirm the index
is genuinely cold (24h+ of zero scans on `pg_stat_user_indexes`).
2026-06-01 09:37:37 +01:00
..
2025-08-27 16:52:58 +01:00
2025-08-27 16:52:58 +01:00
2025-08-27 16:52:58 +01:00
2025-07-30 13:48:02 +01:00

@trigger.dev/database

This is the internal database package for the Trigger.dev project. It exports a generated prisma client that can be instantiated with a connection string.

How to switch branches when you've done migrations

Sometimes you've applied migrations and then want to switch branches without wiping out your local database.

To do this you can run the following command:

DB_VOLUME=database-data-alt pnpm run docker

This will switch to the alt volume for your local database. This database will be blank if you haven't switched to this volume before, so you'll need to follow the normal steps (in the Contributing guide) to get setup, e.g. apply migrations and seed.

To switch back to the original volume, run the following command:

pnpm run docker

How to add a new index on a large table

  1. Modify the Prisma.schema with a single index change (no other changes, just one index at a time)
  2. Create a Prisma migration using cd internal-packages/database && pnpm run db:migrate:dev:create
  3. Modify the SQL file: add IF NOT EXISTS to it and CONCURRENTLY:
CREATE INDEX CONCURRENTLY IF NOT EXISTS "JobRun_eventId_idx" ON "JobRun" ("eventId");
  1. Dont apply the Prisma migration locally yet. This is a good opportunity to test the flow.
  2. Manually apply the index to your database, by running the index command.
  3. Then locally run pnpm run db:migrate:deploy

Before deploying

Run the index creation before deploying

CREATE INDEX CONCURRENTLY IF NOT EXISTS "JobRun_eventId_idx" ON "JobRun" ("eventId");

These commands are useful:

-- creates an index safely, this can take a long time (2 mins maybe)
CREATE INDEX CONCURRENTLY IF NOT EXISTS "JobRun_eventId_idx" ON "JobRun" ("eventId");
-- checks the status of an index
SELECT * FROM pg_stat_progress_create_index WHERE relid = '"JobRun"'::regclass;
-- checks if the index is there
SELECT * FROM pg_indexes WHERE tablename = 'JobRun' AND indexname = 'JobRun_eventId_idx';

Now, when you deploy and prisma runs the migration, it will skip the index creation because it already exists. If you don't do this, there will be pain.