From ec834bf5ac7d095601c0c277ef5ff4597b16cc50 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 1 May 2026 08:22:18 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Parallelize=20independent?= =?UTF-8?q?=20sequential=20database=20queries?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced sequential `await db.select(...)` calls with `Promise.all()` to fetch independent data metrics and counts concurrently in `app/api/products/route.ts` and `lib/actions/admin.ts`. This reduces the request latency significantly by avoiding waterfall execution patterns. Co-authored-by: f4teless <60130665+f4teless@users.noreply.github.com> --- .jules/bolt.md | 3 +++ app/api/products/route.ts | 27 ++++++++++--------- lib/actions/admin.ts | 57 ++++++++++++++++++++------------------- 3 files changed, 46 insertions(+), 41 deletions(-) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..0d2a656 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-06-25 - Parallelize Independent Sequential Drizzle Queries +**Learning:** Found multiple instances where independent database queries (like paginated fetches alongside total count queries, or multiple aggregate queries for a dashboard) were being awaited sequentially using `await db.select(...)`. In this Next.js Drizzle architecture, this creates an unnecessary waterfall of requests, increasing latency. +**Action:** When interacting with the database via Drizzle ORM, parallelize independent sequential queries using `Promise.all([db.select(...), db.select(...)])` to minimize overall request latency. diff --git a/app/api/products/route.ts b/app/api/products/route.ts index 953d709..1072c86 100644 --- a/app/api/products/route.ts +++ b/app/api/products/route.ts @@ -58,19 +58,20 @@ export async function GET(req: NextRequest) { conditions.push(eq(products.isFeatured, true)); } - const result = await db - .select() - .from(products) - .where(and(...conditions)) - .orderBy(desc(products.displayOrder), desc(products.createdAt)) - .limit(limit) - .offset(offset); - - // Get total count for pagination - const [{ count }] = await db - .select({ count: sql`count(*)` }) - .from(products) - .where(and(...conditions)); + // Parallelize data fetch and total count queries to reduce latency + const [result, [{ count }]] = await Promise.all([ + db + .select() + .from(products) + .where(and(...conditions)) + .orderBy(desc(products.displayOrder), desc(products.createdAt)) + .limit(limit) + .offset(offset), + db + .select({ count: sql`count(*)` }) + .from(products) + .where(and(...conditions)) + ]); return NextResponse.json({ products: result, diff --git a/lib/actions/admin.ts b/lib/actions/admin.ts index 54c3848..75fd5b5 100644 --- a/lib/actions/admin.ts +++ b/lib/actions/admin.ts @@ -506,34 +506,35 @@ export async function getDashboardStats() { const now = new Date(); const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000); - // Total products - const [{ count: totalProducts }] = await db - .select({ count: sql`count(*)` }) - .from(products) - .where(eq(products.isActive, true)); - - // Total orders (last 30 days) - const [{ count: totalOrders }] = await db - .select({ count: sql`count(*)` }) - .from(orders) - .where(gte(orders.createdAt, thirtyDaysAgo)); - - // Total revenue (last 30 days) - const [{ sum: totalRevenue }] = await db - .select({ sum: sql`COALESCE(sum(total), 0)` }) - .from(orders) - .where( - and( - gte(orders.createdAt, thirtyDaysAgo), - eq(orders.status, "delivered") - ) - ); - - // Active coupons - const [{ count: activeCoupons }] = await db - .select({ count: sql`count(*)` }) - .from(coupons) - .where(eq(coupons.isActive, true)); + // Run independent sequential queries concurrently to avoid waterfall requests + const [ + [{ count: totalProducts }], + [{ count: totalOrders }], + [{ sum: totalRevenue }], + [{ count: activeCoupons }] + ] = await Promise.all([ + db + .select({ count: sql`count(*)` }) + .from(products) + .where(eq(products.isActive, true)), + db + .select({ count: sql`count(*)` }) + .from(orders) + .where(gte(orders.createdAt, thirtyDaysAgo)), + db + .select({ sum: sql`COALESCE(sum(total), 0)` }) + .from(orders) + .where( + and( + gte(orders.createdAt, thirtyDaysAgo), + eq(orders.status, "delivered") + ) + ), + db + .select({ count: sql`count(*)` }) + .from(coupons) + .where(eq(coupons.isActive, true)) + ]); return { totalProducts: Number(totalProducts),