Skip to content

perf: Optimize findSiblingTranslations to reduce N+1 API calls #139

@luandro

Description

@luandro

Summary

The findSiblingTranslations function in scripts/notion-translate/index.ts makes N+1 API calls to find a sibling translation page, causing unnecessary API credit consumption and latency.

Current Implementation

The function traverses the parent block hierarchy using blocks.children.list and then executes a pagesRetrieve call for every single child page to check its language property.

// Current approach: iterates all children, fetches each page
const childrenResponse = await enhancedNotion.blocksChildrenList({
  block_id: parentBlockId,
});

for (const childRef of pageChildren) {
  // N+1 calls: fetches full page for each child
  const childPage = await enhancedNotion.pagesRetrieve({
    page_id: childRef.id,
  });
  
  const childLanguage = childPage.properties?.[NOTION_PROPERTIES.LANGUAGE]?.select?.name;
  if (childLanguage === targetLanguage) {
    return childPage;
  }
}

Impact

  • API Credit Exhaustion: For a section with 50 pages, this results in 51+ API calls just to find one translation.
  • Latency: Dramatically increases the time required for the "pre-flight" check of large documentation sets.
  • Cost: Each unnecessary API call consumes Notion API credits.

Suggested Solution

Use Notion's query engine to filter by both the Parent item relation AND the target Language in a single call:

const response = await notion.databases.query({
  database_id: DATABASE_ID,
  filter: {
    and: [
      { property: "Parent item", relation: { contains: parentId } },
      { property: "Language", select: { equals: targetLanguage } }
    ]
  }
});

Important Considerations

⚠️ This fix requires careful analysis before implementation:

  1. Two types of "parent" exist in the codebase:

    • page.parent - Notion's built-in structural hierarchy (block_id/page_id)
    • properties["Parent item"] - custom relation field in the database
  2. Current behavior uses structural parent, while the suggested query uses the relation property. These may not always be the same.

  3. Changing this could break existing behavior if:

    • Some pages have a structural parent that differs from their "Parent item" relation
    • The translation logic relies on the current hierarchy traversal
  4. Testing required:

    • Update scripts/notion-translate/index.test.ts tests for findSiblingTranslations
    • Verify behavior with real Notion data

Related Context

  • Original code review: PR-128 Review (context/qa/PR-128-review.md)
  • Commit that addressed other issues: d13b6df (fixed type safety, slug length, and CI parsing)

Priority

Low - This is an optimization rather than a critical bug. The current implementation works correctly but is inefficient for large documentation sets.


Labels: performance, technical-debt

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions