Skip to content

Commit 44bfb67

Browse files
committed
perf(webapp): speed up EnvironmentVariableValue lookups
The /api/v1/projects/:projectRef/envvars/:slug/:name route calls `getEnvironmentWithRedactedSecrets`, which runs a Prisma findMany on EnvironmentVariableValue filtered by environmentId + isSecret. Two issues compound: 1. The only existing indexes are the primary key and a unique on (variableId, environmentId), so environmentId is never the leading column. Postgres falls back to a Parallel Seq Scan over the whole table for what is, in practice, a handful of rows per environment. 2. The repository was running this read on the writer client. Two changes: - Add a btree index on EnvironmentVariableValue(environmentId) so the planner switches to an index scan and the CPU + buffer-pin (LWLock:BufferContent) cost from concurrent calls disappears. - Route this one findMany 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. The composite (variableId, environmentId) unique stays in place; the new index is purely additive.
1 parent 6b46a34 commit 44bfb67

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)