Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## 2025-02-20 - [Performance] Optimize independent backend sequential queries

**Learning:** When retrieving data from Astro DB/Drizzle ORM using multiple `await db.select().from(Table)` queries in an API endpoint, doing so sequentially creates unnecessary sequential I/O bottleneck wait time.
**Action:** Identify independent queries in data retrieval endpoints and group them using `await Promise.all([db.select()..., db.select()...])` to execute them concurrently, reducing total wait time to the longest single query without sacrificing code readability.
9 changes: 6 additions & 3 deletions src/pages/api/agent-budget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ export async function GET({ url }: { url: URL }) {
const agentId = url.searchParams.get('agentId');

// Récupérer tous les budgets (avec infos agents)
const budgets = await db.select().from(AgentBudget);
const allEvents = await db.select().from(CostEvent);
const instructions = await db.select().from(AgentInstruction);
// ⚡ Bolt: Concurrent query execution to avoid sequential I/O bottlenecks
const [budgets, allEvents, instructions] = await Promise.all([
db.select().from(AgentBudget),
db.select().from(CostEvent),
db.select().from(AgentInstruction),
]);
Comment on lines +20 to +25
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While using Promise.all is a correct optimization for concurrency, the queries themselves still fetch all columns from the database.

  1. Efficiency: AgentInstruction contains a systemPrompt field which can be very large and is not used in this endpoint. Similarly, CostEvent fetches several unused columns. Selecting only the required columns will significantly reduce memory usage and network overhead.
  2. Scalability: Fetching all rows from CostEvent will eventually lead to performance issues as the table grows. For future improvement, consider using SQL aggregations (SUM, COUNT) and filtering by date (occurredAt) directly in the query instead of processing everything in JavaScript.
  3. Style: Consider removing the tool-specific branding (⚡ Bolt:) from the comment to maintain a standard, clean codebase.
Suggested change
// ⚡ Bolt: Concurrent query execution to avoid sequential I/O bottlenecks
const [budgets, allEvents, instructions] = await Promise.all([
db.select().from(AgentBudget),
db.select().from(CostEvent),
db.select().from(AgentInstruction),
]);
// Fetch data concurrently to reduce total I/O wait time
const [budgets, allEvents, instructions] = await Promise.all([
db.select().from(AgentBudget),
db.select({
agentId: CostEvent.agentId,
costCents: CostEvent.costCents,
inputTokens: CostEvent.inputTokens,
outputTokens: CostEvent.outputTokens,
occurredAt: CostEvent.occurredAt,
}).from(CostEvent),
db.select({
agentId: AgentInstruction.agentId,
model: AgentInstruction.model,
}).from(AgentInstruction),
]);


// Map agentId → model name
const agentModels: Record<string, string> = {};
Expand Down