Skip to content

Commit 5ef15c8

Browse files
author
Theodore Li
committed
fix(log): log cleanup sql query
1 parent c393791 commit 5ef15c8

File tree

1 file changed

+14
-26
lines changed

1 file changed

+14
-26
lines changed

apps/sim/app/api/logs/cleanup/route.ts

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { db } from '@sim/db'
2-
import { subscription, user, workflowExecutionLogs, workspace } from '@sim/db/schema'
2+
import { subscription, workflowExecutionLogs, workspace } from '@sim/db/schema'
33
import { createLogger } from '@sim/logger'
44
import { and, eq, inArray, isNull, lt } from 'drizzle-orm'
55
import { type NextRequest, NextResponse } from 'next/server'
@@ -26,38 +26,26 @@ export async function GET(request: NextRequest) {
2626
const retentionDate = new Date()
2727
retentionDate.setDate(retentionDate.getDate() - Number(env.FREE_PLAN_LOG_RETENTION_DAYS || '7'))
2828

29-
const freeUsers = await db
30-
.select({ userId: user.id })
31-
.from(user)
29+
/**
30+
* Subquery: workspace IDs whose billed account user has no active paid
31+
* subscription. Kept as a subquery (not materialized into JS) so the
32+
* generated SQL is `WHERE workspace_id IN (SELECT ...)` — this avoids
33+
* PostgreSQL's 65535 bind-parameter limit that was breaking cleanup once
34+
* the free-user count grew beyond ~65k.
35+
*/
36+
const freeWorkspacesSubquery = db
37+
.select({ id: workspace.id })
38+
.from(workspace)
3239
.leftJoin(
3340
subscription,
3441
and(
35-
eq(user.id, subscription.referenceId),
42+
eq(subscription.referenceId, workspace.billedAccountUserId),
3643
inArray(subscription.status, ENTITLED_SUBSCRIPTION_STATUSES),
3744
sqlIsPaid(subscription.plan)
3845
)
3946
)
4047
.where(isNull(subscription.id))
4148

42-
if (freeUsers.length === 0) {
43-
logger.info('No free users found for log cleanup')
44-
return NextResponse.json({ message: 'No free users found for cleanup' })
45-
}
46-
47-
const freeUserIds = freeUsers.map((u) => u.userId)
48-
49-
const workspacesQuery = await db
50-
.select({ id: workspace.id })
51-
.from(workspace)
52-
.where(inArray(workspace.billedAccountUserId, freeUserIds))
53-
54-
if (workspacesQuery.length === 0) {
55-
logger.info('No workspaces found for free users')
56-
return NextResponse.json({ message: 'No workspaces found for cleanup' })
57-
}
58-
59-
const workspaceIds = workspacesQuery.map((w) => w.id)
60-
6149
const results = {
6250
enhancedLogs: {
6351
total: 0,
@@ -83,7 +71,7 @@ export async function GET(request: NextRequest) {
8371
let batchesProcessed = 0
8472
let hasMoreLogs = true
8573

86-
logger.info(`Starting enhanced logs cleanup for ${workspaceIds.length} workspaces`)
74+
logger.info('Starting enhanced logs cleanup for free-plan workspaces')
8775

8876
while (hasMoreLogs && batchesProcessed < MAX_BATCHES) {
8977
const oldEnhancedLogs = await db
@@ -105,7 +93,7 @@ export async function GET(request: NextRequest) {
10593
.from(workflowExecutionLogs)
10694
.where(
10795
and(
108-
inArray(workflowExecutionLogs.workspaceId, workspaceIds),
96+
inArray(workflowExecutionLogs.workspaceId, freeWorkspacesSubquery),
10997
lt(workflowExecutionLogs.createdAt, retentionDate)
11098
)
11199
)

0 commit comments

Comments
 (0)