Skip to content

Commit aec7e0a

Browse files
authored
perf(webapp): index EnvironmentVariableValue.environmentId (#3675)
Env-var lookups via `GET /api/v1/projects/:projectRef/envvars/:slug/:name` run a Prisma `findMany` on `EnvironmentVariableValue` filtered by `environmentId` + `isSecret`. The only existing indexes are the primary key and a unique on `(variableId, environmentId)`, so `environmentId` is never the leading column — the planner falls back to a Parallel Seq Scan over the whole table to find what is, in practice, a handful of rows per environment. Two changes: - Add a btree index on `EnvironmentVariableValue(environmentId)` so the planner switches to an index scan. The composite `(variableId, environmentId)` unique stays in place; the new index is purely additive. - Route the `findMany` inside `getEnvironmentWithRedactedSecrets` through the read replica via a new `replicaClient` constructor param on the repository (defaulting to `$replica`, mirroring how `prismaClient` defaults to `prisma`). Writes and read-after-write methods stay on the primary. ## Test plan - [ ] `pnpm run typecheck --filter webapp` - [ ] Confirm `EXPLAIN` plan flips from Parallel Seq Scan to an index scan - [ ] Existing env-var route tests still pass
1 parent 6b46a34 commit aec7e0a

4 files changed

Lines changed: 16 additions & 3 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
area: webapp
3+
type: improvement
4+
---
5+
6+
Speed up env-var lookups on the projects API by indexing `EnvironmentVariableValue.environmentId`.

apps/webapp/app/v3/environmentVariables/environmentVariablesRepository.server.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Prisma, type PrismaClient, type RuntimeEnvironmentType } from "@trigger
22
import type { AuthenticatedEnvironment } from "@trigger.dev/core/v3/auth/environment";
33
import { z } from "zod";
44
import { environmentFullTitle } from "~/components/environments/EnvironmentLabel";
5-
import { $transaction, prisma } from "~/db.server";
5+
import { $replica, $transaction, prisma, type PrismaReplicaClient } from "~/db.server";
66
import { env } from "~/env.server";
77
import { getSecretStore } from "~/services/secrets/secretStore.server";
88
import { generateFriendlyId } from "../friendlyIdentifiers";
@@ -47,7 +47,10 @@ function parseSecretKey(key: string) {
4747
const SecretValue = z.object({ secret: z.string() });
4848

4949
export class EnvironmentVariablesRepository implements Repository {
50-
constructor(private prismaClient: PrismaClient = prisma) {}
50+
constructor(
51+
private prismaClient: PrismaClient = prisma,
52+
private replicaClient: PrismaReplicaClient = $replica
53+
) {}
5154

5255
async create(projectId: string, options: CreateEnvironmentVariables): Promise<CreateResult> {
5356
const project = await this.prismaClient.project.findFirst({
@@ -582,7 +585,7 @@ export class EnvironmentVariablesRepository implements Repository {
582585
const variables = await this.getEnvironment(projectId, environmentId, parentEnvironmentId);
583586

584587
// Get the keys of all secret variables
585-
const secretValues = await this.prismaClient.environmentVariableValue.findMany({
588+
const secretValues = await this.replicaClient.environmentVariableValue.findMany({
586589
where: {
587590
environmentId: parentEnvironmentId
588591
? { in: [environmentId, parentEnvironmentId] }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-- CreateIndex
2+
CREATE INDEX CONCURRENTLY IF NOT EXISTS "EnvironmentVariableValue_environmentId_idx"
3+
ON "EnvironmentVariableValue"("environmentId");

internal-packages/database/prisma/schema.prisma

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,6 +2020,7 @@ model EnvironmentVariableValue {
20202020
lastUpdatedBy Json?
20212021
20222022
@@unique([variableId, environmentId])
2023+
@@index([environmentId])
20232024
}
20242025

20252026
model Checkpoint {

0 commit comments

Comments
 (0)