perf(admin): cache global admin list totals via redisCache
CI / check (push) Successful in 2m37s
CI / deploy (push) Successful in 18s
CI / publish-container (push) Successful in 1m24s

Introduce getCachedAdminCount to cache un-filtered table count(*) queries in Redis for admin lists (starting with UsersPage), avoiding heavy full table scans on every request while keeping exact counts for search/filtered queries.
This commit is contained in:
openhands committed 2026-09-13 13:32:51 +02:00
1 parent ec742a3f72
commit cbf056838f
2 files changed
+31 -4

No files matched your search

+26
View File
@@ -0,0 +1,26 @@
import { count, type SQL } from "drizzle-orm";
import type { MySqlTable } from "drizzle-orm/mysql-core";
import { db } from "@/lib/db";
import { redisCache } from "@/lib/redis-cache";
/**
* Caches admin list totals when no filters are applied (no 'where' clause),
* preventing heavy COUNT(*) table scans on every request for large tables.
* Filtered queries bypass cache to ensure exact search result counts.
*/
export async function getCachedAdminCount(
table: MySqlTable,
cacheKey: string,
where?: SQL | undefined,
): Promise<number> {
// Only cache the global count (where = undefined)
if (where) {
const [row] = await db.select({ total: count() }).from(table).where(where);
return Number(row?.total ?? 0);
}
return await redisCache(`admin:count:${cacheKey}`, 60, async () => {
const [row] = await db.select({ total: count() }).from(table);
return Number(row?.total ?? 0);
});
}