How I built pairwise AI model compare pages with Claude Haiku and a budget cap A technical approach to generating AI model comparison pages for a directory, where the author reduced the potential 19,900 model pairs to a manageable 50 by only comparing the top 4 models within each of 8 pipeline tags. The system uses Claude Haiku for content generation, employs deterministic slug creation for idempotent nightly ETL runs, and caches system prompts to minimize API costs. The author acknowledges that the current approach misses cross-pipeline comparisons (e.g., Whisper vs Gemini-Vision), which would be more valuable for users unfamiliar with the AI landscape. When I added compare pages to the Top AI Tools directory https://dev.to/articles/three-sites-experiment , the first question I had to answer was: how many pairs am I actually looking at? With roughly 200 models across 8 pipeline tags, the naive upper bound is 200 × 199 / 2 ≈ 19,900 pairs. Generating content for each one with Claude Haiku would cost somewhere around $20 per run — not ruinous, but not something I wanted to run daily without thinking carefully. Here's what I actually built, where it falls short, and what I'd do differently if starting over. The combinatorics problem Model compare pages exist for a specific type of query: "llama 3 vs mistral 7b", "stable diffusion vs sdxl", "whisper vs wav2vec2". These are high-intent queries — the user has already narrowed down to a shortlist and wants a concrete decision nudge. The static SSG approach I'm running https://dev.to/articles/static-ssg-vs-dynamic-ai-rendering-directory-seo means I need to precompute each compare page at build time, which puts pressure on how many pages I can afford to generate. The solution I landed on: group by pipeline tag , pair the top-4 models by download count within each group, then cap total pairs with a COMPARE LIMIT env var. Within a single pipeline like text-generation , the top 4 models give 6 pairs 4 choose 2 . Across 8 active pipelines that's roughly 48 pairs. The env cap of 50 means I stay within that budget while having room to grow. js const byPipe = new Map