Skip to content
Skillv1.0.0

algolia-cost-tuning

Optimize Algolia costs: understand search request vs record pricing, reduce operations with batching and caching, monitor usage via Analytics API. Trigger: "algolia cost", "algolia billing", "reduce a

by jeremylongshore(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from jeremylongshore/tons-of-skills-marketplace (skills/.curated/algolia-cost-tuning/SKILL.md). Install upstream with npx skills add jeremylongshore/tons-of-skills-marketplace --skill algolia-cost-tuning. Copyright stays with the author (MIT).

Algolia Cost Tuning

Overview

Algolia pricing is based on search requests and records. A search request is one API call (which may contain multiple queries via search({ requests: [...] })). Records are counted across all indices including replicas.

Prerequisites

  • Access to current Algolia usage, billing, and index statistics for the application being reviewed.
  • An Admin or monitoring credential used only from a trusted backend environment.
  • A reporting window that distinguishes production traffic from load tests and bots.

Pricing Structure (2025)

Plan Records Included Search Requests Additional Cost
Build (Free) 1M records 10K requests/mo N/A
Grow 100K free, then $0.40/1K 10K free, then $0.50/1K Pay as you go
Grow Plus 100K free, then $0.40/1K 10K free, then $1.75/1K + AI features
Premium Custom Custom Volume discounts

What Counts as Records

  • Every object in every index = 1 record
  • Standard replicas duplicate records (multiply your count)
  • Virtual replicas share records (no extra cost)
  • Synonyms and rules do NOT count as records

What Counts as Search Requests

  • searchSingleIndex() = 1 request
  • search({ requests: [q1, q2, q3] }) = 1 request (multi-query)
  • browse() = 1 request per page
  • saveObjects() = NOT a search request (indexing operations are free)

Instructions

Examples

The audit and analytics calls below show how to measure records, requests, and no-result searches before changing replicas, caching, or query design. Measure a baseline first so savings claims are testable.

Step 1: Audit Current Usage

import { algoliasearch } from 'algoliasearch';

const client = algoliasearch(process.env.ALGOLIA_APP_ID!, process.env.ALGOLIA_ADMIN_KEY!);

// Check total records across all indices
const { items } = await client.listIndices();
let totalRecords = 0;
let replicaRecords = 0;

items.forEach(idx => {
  const records = idx.entries || 0;
  console.log(`${idx.name}: ${records.toLocaleString()} records, ${(idx.dataSize || 0 / 1024).toFixed(0)}KB`);
  if (idx.name.includes('_replica') || idx.primary) {
    replicaRecords += records;
  }
  totalRecords += records;
});

console.log(`\nTotal: ${totalRecords.toLocaleString()} records (${replicaRecords.toLocaleString()} in replicas)`);

Step 2: Replace Standard Replicas with Virtual Replicas

// Standard replicas: duplicate all records (doubles cost)
// Virtual replicas: share records with primary (no extra cost)

// BEFORE: 3 standard replicas = 4x record count
await client.setSettings({
  indexName: 'products',
  indexSettings: {
    replicas: [
      // 'products_price_asc',      // Standard: costs records
      // 'products_price_desc',     // Standard: costs records
      'virtual(products_price_asc)',  // Virtual: FREE
      'virtual(products_price_desc)', // Virtual: FREE
    ],
  },
});

// Virtual replica limitation: can only customize ranking and customRanking
// If you need different searchableAttributes or attributesForFaceting, use standard

Step 3: Use Multi-Query to Reduce Request Count

// BAD: 3 separate requests = 3 search operations billed
const results1 = await client.searchSingleIndex({ indexName: 'products', searchParams: { query: 'laptop' } });
const results2 = await client.searchSingleIndex({ indexName: 'articles', searchParams: { query: 'laptop' } });
const results3 = await client.searchSingleIndex({ indexName: 'faq', searchParams: { query: 'laptop' } });

// GOOD: 1 multi-query request = 1 search operation billed
const { results } = await client.search({
  requests: [
    { indexName: 'products', query: 'laptop', hitsPerPage: 5 },
    { indexName: 'articles', query: 'laptop', hitsPerPage: 3 },
    { indexName: 'faq', query: 'laptop', hitsPerPage: 3 },
  ],
});

Step 4: Cache Frequent Searches

import { LRUCache } from 'lru-cache';

// Cache popular searches — Algolia's own CDN caches are limited
const searchCache = new LRUCache<string, any>({
  max: 1000,
  ttl: 5 * 60 * 1000, // 5 minutes for product search
});

async function cachedSearch(query: string, filters?: string) {
  const key = JSON.stringify({ query, filters });
  const cached = searchCache.get(key);
  if (cached) {
    console.log('Cache hit — saved 1 search request');
    return cached;
  }
  const result = await client.searchSingleIndex({
    indexName: 'products',
    searchParams: { query, filters },
  });
  searchCache.set(key, result);
  return result;
}

Step 5: Delete Unused Indices

// Audit and clean up test/development indices
const { items } = await client.listIndices();
const devIndices = items.filter(i =>
  i.name.startsWith('test_') ||
  i.name.startsWith('dev_') ||
  i.name.startsWith('ci_')
);

for (const idx of devIndices) {
  console.log(`Deleting unused index: ${idx.name} (${idx.entries} records)`);
  await client.deleteIndex({ indexName: idx.name });
}

Step 6: Monitor Usage with Analytics API

// Track search volume trends
const { count: searchCount } = await client.getSearchesCount({
  index: 'products',
  startDate: '2025-01-01',
  endDate: '2025-01-31',
});
console.log(`Search requests this month: ${searchCount.toLocaleString()}`);

// Identify no-result queries (wasted searches users will retry)
const { searches } = await client.getSearchesNoResults({
  index: 'products',
  startDate: '2025-01-01',
  endDate: '2025-01-31',
});
console.log('Top no-result searches (fix these to reduce retries):');
searches.slice(0, 10).forEach(s => console.log(`  "${s.search}" — ${s.count} times`));

Cost Reduction Summary

Strategy Savings Effort
Virtual replicas 50-75% record cost Low
Multi-query search 60-80% fewer requests Low
Client-side caching 30-50% fewer requests Low
Delete unused indices Variable Low
Fix no-result queries (synonyms) 10-20% fewer retries Medium
Reduce record size Indirect (faster = cheaper) Medium

Output

The review identifies the record and request drivers of the current bill, produces a prioritized reduction plan, and gives measurable before/after signals for each change. It does not alter billing settings by itself.

Error Handling

Issue Cause Solution
Unexpected bill spike Uncached bot traffic Add rate limiting, cache layer
Record count higher than expected Standard replicas Switch to virtual replicas
Search requests over budget No caching Add LRU cache in API layer
Analytics API returns empty Wrong date range or region Check region parameter matches your app

Resources

Next Steps

For architecture patterns, see algolia-reference-architecture.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/jeremylongshore-tons-of-skills-marketplace-algolia-cost-tuning/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

jeremylongshore-tons-of-skills-marketplace-algolia-cost-tuning.ocm.jsonjson
{
  "ocm": "1",
  "id": "jeremylongshore-tons-of-skills-marketplace-algolia-cost-tuning",
  "kind": "skill",
  "name": "algolia-cost-tuning",
  "description": "Optimize Algolia costs: understand search request vs record pricing, reduce operations with batching and caching, monitor usage via Analytics API. Trigger: \"algolia cost\", \"algolia billing\", \"reduce algolia costs\", \"algolia pricing\", \"algolia expensive\", \"algolia budget\".",
  "publisher": "jeremylongshore",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "coding",
      "finance"
    ],
    "tags": [
      "skill-md",
      "saas",
      "search",
      "algolia",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Optimize Algolia costs: understand search request vs record pricing, reduce operations with batching and caching, monitor usage via Analytics API. Trigger: \"algolia cost\", \"algolia billing\", \"reduce algolia costs\", \"algolia pricing\", \"algolia expensive\", \"algolia budget\"."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/jeremylongshore/tons-of-skills-marketplace",
      "path": "skills/.curated/algolia-cost-tuning/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/jeremylongshore/tons-of-skills-marketplace/blob/HEAD/skills/.curated/algolia-cost-tuning/SKILL.md",
      "key": "jeremylongshore/tons-of-skills-marketplace/skills/.curated/algolia-cost-tuning/SKILL.md"
    },
    "compatibility": "Designed for Claude Code",
    "allowed_tools": [
      "Read,",
      "Grep"
    ],
    "license": "MIT"
  },
  "instructions": "# Algolia Cost Tuning\n\n## Overview\n\nAlgolia pricing is based on **search requests** and **records**. A search request is one API call (which may contain multiple queries via `search({ requests: [...] })`). Records are counted across all indices including replicas.\n\n## Prerequisites\n\n- Access to current Algolia usage, billing, and index statistics for the application being reviewed.\n- An Admin or monitoring credential used only from a trusted backend environment.\n- A reporting window that distinguishes production traffic from load tests and bots.\n\n## Pricing Structure (2025)\n\n| Plan | Records I",
  "cost": {
    "context_tokens": 1820
  }
}

Fetch it by URL: GET /api/v1/registry/jeremylongshore-tons-of-skills-marketplace-algolia-cost-tuning/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.