Open-Source Caching Proxy

Slash Your Algolia
Costs by Up to 99%

QuerySaver deploys a high-performance Cloudflare Worker proxy that caches your Algolia search queries at the CDN edge. Cached requests never reach Algolia — saving you thousands in monthly API costs.

Drop-in replacement 1-min setup Apache 2.0
algolia-client.js
import algoliasearch from 'algoliasearch';
const client = algoliasearch(
'APP_ID', 'SEARCH_KEY',
{
hosts: [
{ url: "your-cache.workers.dev" }// Cloudflare Edge
]
}
);
Monthly Cost at 10M searches
Direct Algolia$4,995 /mo
With QuerySaver$5 /mo
💸 Up to 99.89% savings
Architecture

How It Works

A transparent caching layer that sits between your frontend and Algolia, powered by Cloudflare Workers.

01

Intercept & Cleanse

The Cloudflare Worker catches the incoming POST request and strips user-specific tokens like userToken for cache homogenization.

02

SHA-256 Hashing

Generates a deterministic SHA-256 hash of the cleansed payload — ensuring identical queries always map to the same cache key.

03

"Ghost GET" Cache Check

Translates the hash into a simulated GET URL — a workaround that enables Cloudflare's Cache API to store POST responses at the edge.

04

Resolve in Milliseconds

Cache hits resolve instantly (~10ms) from the nearest edge node. Misses are forwarded to Algolia and cached in the background.

🌐 UserBrowser / App⚡ WorkerHash & Route📦 EdgeCache📊 AlgoliaOriginPOSTGET /cacheMISS only⚡ Cache HIT → ~10ms
Why QuerySaver

Built for Performance & Savings

Everything you need to optimize your Algolia costs without sacrificing search speed.

Up to 99% Cost Reduction

Cached requests never reach Algolia servers. Drastically reduce your billable search operations and monthly API spend.

Blazing Fast Speeds

Serve cached results from the nearest Cloudflare edge node in ~10-30ms — faster than a direct Algolia query.

Easy Integration

Just swap the host URL in your Algolia client config. Works with all frontend SDKs — React, Vue, Angular, vanilla JS.

Multi-App & Multi-Index

Deploy once and proxy all your Algolia applications. The SHA-256 cache key natively prevents cross-index cache collisions.

Privacy-Safe Caching

User-specific tokens are stripped before hashing. Identical queries share a single global cache entry — no PII leaks.

Global Edge Network

Leverage Cloudflare's 300+ worldwide data centers. Every user hits the nearest PoP for ultra-low latency responses.

Cost Comparison

The Numbers Speak for Themselves

See how much you could save by routing Algolia queries through QuerySaver's Cloudflare edge cache.

Searches / MonthDirect AlgoliaWith QuerySaverSavings
10,000$0 (Free)$0 (Free)0%
100,000~$45$0 (Free)100%
1,000,000~$495$0 (Free)100%
10,000,000~$4,995~$5~99.89%
100,000,000~$49,995~$27~99.95%
* Assumes cache is cleared once a month. Actual savings depend on traffic patterns and cache hit rate.

Start Saving in Under a Minute

Clone the repository, deploy to Cloudflare, and point your Algolia client to your new Worker URL. That's it.

terminal
$ git clone https://github.com/MarcinKilarski/algolia-caching-proxy-via-cloudflare-worker.git
$ cd algolia-caching-proxy-via-cloudflare-worker && npm install
$ npx wrangler login && npm run deploy
✓ Worker deployed to your-worker.workers.dev
Got Questions?

Frequently Asked Questions

It intercepts Algolia search POST requests originating from your frontend. It checks if the exact same search has been made recently, and if so, returns the result instantly from Cloudflare's Edge Cache instead of hitting Algolia's servers and consuming your quota.

No, this is an independent, open-source community project. It is not affiliated with, endorsed by, or supported by Algolia or Cloudflare.

If your site has highly repetitive searches (like e-commerce, documentation hubs, or media portals), you can reduce your billable Algolia operations by up to 99%, depending on your cache TTL and traffic volume.

No. In fact, cache hits are served directly from the nearest Cloudflare Edge node to the user, resulting in ultra-fast responses (~10-30ms) compared to a full trip to Algolia. Cache misses incur a tiny 50ms penalty.

By configuring Algolia's official fallback hosts in your frontend client, Algolia's SDK guarantees that if the first host fails (your Worker), the query seamlessly routes to official Algolia servers without breaking the frontend experience.

Yes! It is completely plug-and-play compatible with all Algolia frontend libraries (InstantSearch, React, Vue, pure JS) without any modifications to how InstantSearch works.

You can manually invalidate the Cloudflare Edge cache via the Cloudflare Dashboard UI or programmatically via a Headless cURL request using Cloudflare's API. This behavior requires a Custom Domain.

A Custom Domain unlocks Cloudflare's Smart Tiered Cache (which drastically increases cache hit rates by routing requests through regional hubs) and allows you to manually purge the cache, which isn't natively possible on a default `.workers.dev` subdomain.

No. To ensure a high cache hit rate globally across all users, user-specific tokens (`userToken`) are stripped. Native Algolia personalization features will not work through this proxy.

Yes. Since cached requests never physically reach Algolia, your internal Algolia dashboard analytics will underreport search volume. AI features like Dynamic Re-Ranking and Query Categorization will also be severely affected.

You should configure Cloudflare Rate Limiting (WAF Rules) on your Custom Domain to aggressively block IPs making an unnatural volume of random, unique search requests intentionally designed to bypass the cache.

No. This proxy is designed exclusively for Search (Read) requests. You should not route your backend indexing or write operations through this proxy, they will fail.

The unique cache key natively incorporates the API Key and query payload in its mathematical hash, while preserving the Algolia Application ID and Index Name within the URL path structure. This means it safely supports querying completely different Algolia Applications and Indexes simultaneously without cache bleeding.

Yes, absolutely. You only need to change the `hosts` array during the frontend initialization of the Algolia client. It continues to work normally within your framework of choice's InstantSearch wrapper.

This heavily depends on your specific traffic patterns. High-traffic sites with common queries or high-volume default empty queries will see very high cache hit rates, while sites with entirely unique, long-tail queries will see lower hit rates.

By default, results are cached at the Cloudflare Edge for 1 month (`CDN_CACHE_TTL`) and in the user's browser for 1 hour (`BROWSER_CACHE_TTL`). Both values can be easily adjusted in `src/config.js`.

Both. It returns specific `Cache-Control` headers that instruct the user's local browser to cache the response for `BROWSER_CACHE_TTL`, and Cloudflare's CDN to cache it for `CDN_CACHE_TTL`.

In `src/config.js`, you should change the `ALLOWED_ORIGIN` rule from `['*']` to strictly contain your actual frontend production domains to prevent unauthorized API requests against your project payload.

While Algolia's Terms of Service generally do not explicitly ban CDN caching middle-layers (which are standard architectural patterns), it does reduce their revenue. As this is an open-source tool running on your own infrastructure, you are responsible for mitigating risks and reviewing the ToS of any service provider.

No. If you use Algolia A/B testing dynamically behind the scenes, Cloudflare Edge caches might lock onto a specific A/B variant on the first cache miss and erroneously serve it universally to all users.

Yes, as long as the requests are made via HTTP POST. However, since Algolia Recommend relies heavily on user behavior and personalization, aggressive edge caching might degrade the effectiveness of the recommendations.

Inspect the network tab in your browser's developer tools. Look at the response headers for your search request. The `cf-cache-status` header will indicate `HIT` (served from cache) or `MISS` (served from Algolia).

This proxy is designed for public data. If you use Algolia Secured API Keys with embedded filters for row-level security, they will be cached based on the token. However, you must carefully modify the proxy to not strip role-identifying tokens, otherwise users might see unauthorized cached data.

The Worker itself doesn't inherently rate-limit, but by routing traffic through Cloudflare, you can easily apply Cloudflare's Web Application Firewall (WAF) and Rate Limiting rules before the request even reaches your Algolia quota.

Absolutely! In fact, it is highly recommended. It helps prevent accidental traffic spikes or scrapers from silently exhausting your 10,000 monthly search limit.

No. Standard Algolia Rules (e.g., pinning an item, synonyms) execute on Algolia's servers. The cached response will correctly contain the rule-applied results. Changing a rule simply requires purging the cache.

Yes. The requested index name is part of the URL path, meaning it naturally becomes part of the unique URL cache key, while the payload is independently hashed. Two identical searches on different indices will generate two distinct cache entries.

Yes. Autocomplete queries are fundamentally just standard Algolia search requests. Since they trigger on every keystroke, caching them saves enormous amounts of quota.

Yes. Update your iOS or Android Algolia SDK initialization slightly to point its custom host array to your Cloudflare Worker's URL. The network layer handles the rest.

Empty results (0 hits) are still valid 200 OK HTTP responses from Algolia. The proxy caches these too, which prevents users (or scrapers) spamming invalid queries from draining your quota.

You would handle this in your frontend routing logic. Standard queries use an Algolia client pointing to Cloudflare; real-time critical queries use a separate Algolia client pointing directly to Algolia.

Highly unlikely. Stripping JSON and generating a SHA-256 hash takes fractions of a millisecond, well below Cloudflare's 10ms (free) or 50ms (paid) CPU limits.

You could modify the code to do so, but the native Cache API is significantly faster, strictly designed for HTTP payload storage, and doesn't incur the granular read/write costs of KV.

Cloudflare's Cache API natively supports caching massive response payloads (up to 512MB). For incoming search queries, the POST payload sent by the user must simply stay under Cloudflare Workers' generous 100MB incoming request limit, which is safely well above anything Algolia would typically accept.

Yes. When InstantSearch loads, it often fires an empty query `""` to populate the initial UI. Because every user triggers this exact same query, caching it yields the highest savings.

The proxy only caches `200 OK` responses. Any error codes returned by Algolia are passed directly back to the client and bypass the edge cache.

No. The worker returns the exact, byte-for-byte JSON response provided by Algolia. Your frontend libraries will not notice any difference.

Yes. All facet selections, filters, and numeric ranges are included in the POST body. The proxy hashes the entire body, meaning `color:red` and `color:blue` queries are correctly cached as separate requests.

Yes, you can edit the worker to validate JWTs or verify custom headers before processing the request, providing an extra layer of security before Cloudflare even checks the cache.

Yes. A SHA-256 collision is virtually impossible. Even with trillions of unique search possibilities, you will not experience cache collisions crossing over to different queries.

Deploy two separate Cloudflare Workers (e.g., `algolia-proxy-staging` and `algolia-proxy-prod`), or use Cloudflare's environment variables to manage different ALLOWED_ORIGIN configurations.

Algolia does utilize internal engine-level caching for speed. However, you are still billed for the network request reaching their servers. Our Cloudflare Worker prevents the request from reaching them entirely.

Yes, you can enable Cloudflare Logpush or Worker Analytics on your dashboard to monitor traffic, or add a `console.log` inside the worker and tail it using `wrangler tail`.

Algolia's Terms of Service generally do not prohibit standard CDN caching layers (a standard architectural pattern). However, since it deliberately reduces their billable revenue, you should review your specific enterprise contract if applicable.

Yes. Because it is a standard Cloudflare Worker, you can manage and deploy the script using the Cloudflare Terraform provider or Pulumi just like any other worker.

Yes. The worker simply acts as a standard HTTP client forwarding the payload to the provided Algolia endpoint. DSN routing rules still apply on cache misses.

The next wave of requests will be "Cache Misses" and will hit Algolia directly. Once Algolia responds, Cloudflare will instantly re-populate the edge nodes, shielding Algolia again.

No. Because the Worker programmatically manages the Cache API using the "Ghost GET Request" workaround, standard Cloudflare Page Rules (which operate at the routing level) will not affect it.

Browser caching only benefits a single user *after* they search for something twice. Edge caching benefits *all* users globally the moment *any* single user searches for it once.

Yes! If you have custom parameters that don't affect search results but vary per user (like analytics tags), open `src/utils.js` and add those keys to the `normalizeAlgoliaBody` function to improve your hit rate.

Yes, you can easily implement `stale-while-revalidate` by returning the appropriate `Cache-Control` header from the Worker. This serves a slightly stale cached response to the user immediately while re-fetching fresh data from Algolia in the background.

Yes, you can switch the worker to the 'Unbound' usage model if you anticipate processing payloads or background tasks that need more than the standard 50ms CPU time threshold given in the 'Bundled' pricing model, though this is rarely necessary for this specific use case.

Cloudflare allows "Purge by Cache-Tag" or "Purge by URL" on Enterprise plans. If on a lower tier, you can strictly purge by the specific "Ghost GET Request" URL if you know the exact SHA-256 hash of the payload you wish to clear, but generally, bulk purging `purge_everything` is standard for database syncs.

Because all traffic paths through Cloudflare's Edge, Algolia might see a high volume of requests coming from Cloudflare IPs. Algolia usually trusts Cloudflare IPs natively, but to be completely safe, the Worker should forward the true client IP using the `X-Forwarded-For` and `CF-Connecting-IP` headers so Algolia applies limits correctly.

Cloudflare's native Cache API (`cache.put()`) explicitly rejects any `Request` object with a `POST` method. To utilize the blazing fast, free CDN Edge Cache, the Worker must trick the Cache API by converting the `POST` payload into a deterministic `GET` request URL.

While the proxy is primarily built around the `/queries` search endpoint, it can theoretically be expanded to handle `GET /1/indexes/*/` objects. However, since `GET` requests are natively cacheable, you wouldn't need the complex payload-hashing logic.

Yes! The proxy intercepts the single POST request that contains the array of multiple queries. The hash is generated based on the entire array. Consequently, the combination of those multiple queries is cached as one unified response.

Yes. You can route server-side fetches through the proxy. Since React Server Components hit the Cloudflare Worker instead of Algolia, the server-to-server latency is significantly reduced during Next.js SSR or SSG builds.

Yes, similarly to Next.js, framework meta-routing tools that execute server-side searches during SSR can dramatically benefit from hitting the Cloudflare Edge Worker rather than routing all the way to Algolia's central servers.

Cloudflare handles large streaming responses gracefully. The caching size limitation of a single cached file on Cloudflare is 512MB by default, meaning even the most excessively massive JSON Algolia responses fits safely without truncation.

Yes, you can layer Cloudflare Zero Trust (Access) in front of the staging version of this Worker. This restricts access to the staging indices purely to developers authenticated via your identity provider (Google, Okta, etc.), shielding sensitive data.

If `caches.default.match()` fails due to a rare internal Cloudflare error, the Worker will generally fallback via the `catch` block and gracefully function as a pure pass-through proxy, guaranteeing the user gets their search results directly from Algolia.

Yes. The worker ensures that all strictly required CORS headers (`Access-Control-Allow-Origin`, `Access-Control-Allow-Headers`) are appended to the frozen Cache response before serving it, so the browser doesn't block the cached payload.

Absolutely. Simply extract the JSON from the Algolia response, modify the `hits` array or metadata (e.g., adding promotional banners or filtering restricted items), serialize it back to JSON, `cache.put()` it, and return it to the user.

You can utilize Cloudflare Logpush to stream all Worker execution logs natively to Datadog. Alternatively, you can catch errors and perform a non-blocking `ctx.waitUntil(fetch("sentry-url"))` call inside the Worker logic.

Yes. Cloudflare's network natively negotiates compression with the user's browser (Brotli/zstd/gzip). The response delivered from the Edge cache is compressed automatically, saving bandwidth and accelerating TTFB.

Yes, you can utilize `request.cf.country` or `request.cf.city` inside the Worker to append a geo-identifier to the SHA-256 hash. This forces users in the US to receive a different cached Algolia payload than users in the EU.

Yes. Because the explicit intent of this proxy is to strip PII (like `userToken`) before hashing and returning public, homogenized data, it does not permanently store any personalized data on Cloudflare's servers.

For cache hits, TTFB is massively improved (often dropping from 150ms to 15ms) because the TCP handshake and payload generation conclude locally at the Cloudflare Edge rather than traversing across continents to the Algolia server.

No. Algolia natively incorporates sort strategies into the payload parameters (e.g., via different index targets or specific filters). The POST body differs, resulting in two distinct SHA-256 hashes, keeping the caches accurately segmented.

Immensely. Since malicious high-volume requests identical in nature are caught directly at the edge, an L7 DDoS attack hitting the same query continually will be instantly soaked up by Cloudflare's Cache free of charge. Your Algolia quota remains completely untouched.

No. Cloudflare natively handles `OPTIONS` requests extremely quickly. The proxy responds to them correctly based on the `ALLOWED_ORIGIN` rules defined in `config.js`, avoiding the need to forcefully cache them.

Yes. The proxy forwards the Cache Miss payload directly to your Algolia App ID and its respective global/regional DSN cluster. You don't need to change any logic inside the proxy; Algolia routes the request natively.

Yes. You can intercept the JSON body, intercept the `query` string, run it through a lightweight spell-checker, alter it, and pass the new payload to Algolia. The result of the altered query will then be securely cached.

By default, they remain in the payload and are sent to Algolia. However, due to user-homogenization, the analytics will be vastly warped. It's recommended to either refrain from utilizing `clickAnalytics` or manually strip the parameter inside `utils.js` before hashing.

No. Using Cloudflare's `ctx.waitUntil()` ensures that the user receives their HTTP response immediately, while the caching mechanism finishes processing in the background asynchronously without impacting latency.

If a browser cancels an inflight HTTP connection on a Cache Hit, nothing changes. On a Cache Miss, the proxy may still finish the background request to Algolia and subsequently populate the edge cache anyway, meaning the next query is pre-warmed.

Yes. Because the explicit Application ID is natively extracted and mapped into the routed request url path while the API Key is mathematically hashed, different applications interacting with the single worker naturally segment their caches, removing any risk of cross-application data bleeding.

The Worker has native jurisdiction over ignoring or bypassing cache rules. By default, it ignores client-side request cache-busting directives to strictly preserve the security of your Algolia bill against forced-fetch scripts.

Yes! If you do not want your UI to populate with raw un-searched inventory upon load, you can instruct the Worker to return a dummy `{"hits": []}` response manually when `query=""`, completely zeroing out that quota usage.

No. Algolia Crawler is a backend indexing pipeline meant to scrape URLs and push content to Algolia databases. The proxy acts as a read-only endpoint optimized for frontend query consumption, not backend ingestion.

Yes. Cloudflare enables HTTP/3 natively. The connection between your user's browser and the Edge Worker operates over QUIC, delivering the cached payload remarkably fast, especially on mobile networks.

While mechanically possible, accessing an SQL row in D1 for every caching operation carries significant latency and read/write execution costs compared to the native memory-speed of the distributed Edge Cache API.

Yes. Because the Worker maps cached requests to pseudo `GET` URLs on your custom domain, you can query Cloudflare's GraphQL API to precisely graph the volume of Cache Hits versus Misses for your Worker path.

The proxy translates the SHA-256 hash (64 characters) into a path `https://your-worker-domain.com/cache/1/indexes/YOUR_INDEX_NAME/queries/<hash>`. Therefore, the URL length is completely predictable and well under any CDN or protocol limit (e.g., 2048 characters).

Yes! In the case of a Cache Miss, you can execute a `fetch` sequentially or simultaneously to both Algolia and your private database (or another service), map and merge the JSON objects, and `cache.put()` the resulting hybrid payload.

The local Wrangler development server (`npm run dev`) utilizes an emulated version of Cloudflare's Cache API via `Miniflare`. It allows you to simulate Cache Hits, Misses, and TTL expirations precisely as they will operate in production.

Yes. Generally, the proxy passes along non-sensitive headers (like `User-Agent`, `Referer`) into the `fetch` request heading to Algolia, though this rarely affects search results.

Algolia maintains very high threshold allocations specifically because massive corporate gateways (like Cloudflare) funnel massive amounts of traffic through singular egress IPs. Plus, most queries never reach Algolia due to the high cache hit rate.

Yes. You can implement conditional branching in `index.js` where `if (request.headers.get("X-Bypass-Cache") === "true")` forces the system to skip the `caches.default.match` checking and directly forward the request to the Algolia origin.

Cloudflare does not bill for egress bandwidth. The Worker executes within the free tier usage or minimal compute usage bill. Therefore, serving massive JSON payloads from the Edge will absolutely not affect your Cloudflare CDN bill.

Yes. You can wire the Analytics Engine directly into the Worker to log granular, custom metrics—such as which specific search terms triggered Cache Misses—without passing any load to your Algolia dashboard.

Yes. NeuralSearch acts strictly during index generation and semantic evaluation on Algolia's servers. From the frontend perspective, the client simply submits a query, which the proxy intercepts and safely caches just like any standard query.

This proxy functions implicitly for "Search-Only" API Keys designed for public exposure. Using an Admin Key is explicitly forbidden from frontend requests, as it carries total system access risks outside of simple caching concerns.

By default, if 100 users query exactly the same payload before the cache validates, 100 identical requests will reach Algolia (Cache Stampede). However, deploying complex in-flight concurrency locks within Workers is possible but rarely needed at this scale.

Users will receive the old cached document until the `CDN_CACHE_TTL` organically lapses. To forcefully synchronize the frontend with an instant backend database update, you must configure a cache-purge webhook from your CI/CD or backend pipeline.

Yes. You can utilize a separate Cloudflare Cron Trigger or GitHub Actions script to fire identical `POST` payloads on a scheduled basis, automatically populating the edge cache during low-traffic periods so visitors never experience a slow response.

Page variables are contained inside the payload. E.g., substituting `{"page": 0}` with `{"page": 1}` alters the SHA-256 hash completely. Thus, every specific page of a search sequence is uniquely cached alongside its core query payload.

Yes. In the event Algolia serves a 5xx timeout error on a Cache Miss, you can configure the Worker to instantly return a customized "System currently unavailable" mock JSON response format avoiding a crashing front-end UI.

While replacing Algolia's native network SDK routing with a single domain presents slightly higher SPOF risks, guaranteeing the utilization of the backup Fallback Hosts embedded in the frontend configuration eliminates virtually all of this downtime risk.