Billing - optimize usageEvent CH table (#20019)

- Update usageEvent clickhouse table, partitioning, indexing and
projection (auto materialized view) to optimize credit usage queries
- Add caching for available credits and billing subscription


To do in next PR: deprecate enforceCapUsage cron. Bonus : real-time on
billingSubscription
This commit is contained in:
Etienne
2026-04-28 16:06:49 +02:00
committed by GitHub
parent 2a3b8adcfb
commit fbaea0639a
33 changed files with 601 additions and 379 deletions
@@ -5,7 +5,7 @@ import { Injectable, Logger } from '@nestjs/common';
import { EventLogTable } from 'twenty-shared/types';
import { ClickHouseService } from 'src/database/clickHouse/clickHouse.service';
import { formatDateForClickHouse } from 'src/database/clickHouse/clickHouse.util';
import { formatDateTimeForClickHouse } from 'src/database/clickHouse/clickHouse.util';
const CLICKHOUSE_TABLE_NAMES: Record<EventLogTable, string> = {
[EventLogTable.WORKSPACE_EVENT]: 'workspaceEvent',
@@ -52,7 +52,7 @@ export class EventLogCleanupService {
`ALTER TABLE ${tableName} DELETE WHERE "workspaceId" = {workspaceId:String} AND "timestamp" < {cutoffDate:DateTime64(3)}`,
{
workspaceId,
cutoffDate: formatDateForClickHouse(cutoffDate),
cutoffDate: formatDateTimeForClickHouse(cutoffDate),
},
);
@@ -8,7 +8,7 @@ import { isDefined } from 'twenty-shared/utils';
import { Repository } from 'typeorm';
import { ClickHouseService } from 'src/database/clickHouse/clickHouse.service';
import { formatDateForClickHouse } from 'src/database/clickHouse/clickHouse.util';
import { formatDateTimeForClickHouse } from 'src/database/clickHouse/clickHouse.util';
import { BillingEntitlementKey } from 'src/engine/core-modules/billing/enums/billing-entitlement-key.enum';
import { BillingService } from 'src/engine/core-modules/billing/services/billing.service';
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
@@ -235,12 +235,12 @@ export class EventLogsService {
if (isDefined(filters.dateRange?.start)) {
whereClauses.push('"timestamp" >= {startDate:DateTime64(3)}');
params.startDate = formatDateForClickHouse(filters.dateRange.start);
params.startDate = formatDateTimeForClickHouse(filters.dateRange.start);
}
if (isDefined(filters.dateRange?.end)) {
whereClauses.push('"timestamp" <= {endDate:DateTime64(3)}');
params.endDate = formatDateForClickHouse(filters.dateRange.end);
params.endDate = formatDateTimeForClickHouse(filters.dateRange.end);
}
if (table === EventLogTable.OBJECT_EVENT) {