caching, privacy, PHP, Laravel, performance, System design
A privacy-preserving favicon cache for a search engine's results page
**A single results page renders favicons for hundreds of third-party sites; serving each one from its origin would leak the searcher's browsing to every one of those hosts. I built the cache that serves them all from Presearch's own domain instead, at img.presearch.org, so no favicon fetch reaches a site the user never chose to visit.**
## Outcome
I built the cache behind img.presearch.org so search-result favicons are served from Presearch's domain and third-party sites never receive a browser request from the searcher.
## Context
This work was for Presearch, a privacy-focused search engine whose results pages can display hundreds of third-party favicons for a single query. I owned the cache implementation as a contract contributor within the wider product and infrastructure context.
## Problem
Presearch is a privacy-focused search engine. Every results page shows a small favicon next to each result, and a single query can surface hundreds of them. The obvious implementation, letting the browser hotlink each favicon straight from the result's own domain, quietly defeats the entire premise: every one of those hosts would receive a request carrying the user's IP and referer the moment the page rendered, turning the results view into a broadcast of what the searcher is looking at. It is also slow and fragile, because the page now depends on hundreds of uncontrolled third-party servers, any of which can be down, sluggish, or serving something unexpected.
## Constraints
- Privacy is the product, not a feature: no favicon request may reach a third-party host on the user's behalf.
- Volume is high and bursty. One results page fans out to many favicons, and popular domains repeat across millions of queries.
- The per-asset budget is tiny. A favicon is a rounding error next to the result it decorates, so fetching, storing, and serving one has to stay cheap in both time and disk.
## Decisions and trade-offs
**Serve from our own domain over hotlink pass-through.** The tempting path was to proxy or rewrite favicon URLs to their origins. Rejected outright: that is the tracking leak the search engine exists to prevent. Instead every favicon is fetched server-side once, stored, and served from img.presearch.org, so the browser only ever talks to Presearch. The favicon source itself is resolved either from a known icon file or by parsing the site's HTML for its declared icon, with a custom fetch capped at a 2-second timeout so one slow or dead host can never stall the path.
**Bounded cache with expiry over an unbounded store.** Caching every favicon forever is simple until disk and memory grow without limit and stale icons never refresh. Rejected. The cache expires entries on modification time, and on expiry the response carries no-cache headers so a stale icon is not pinned downstream. A scheduled cleanup job sweeps expired entries, and I optimized that cleanup path for memory so the sweep itself stays cheap at volume rather than loading the whole cache to prune it. A favicon-policy test suite locks the fetch, expiry, and header behavior in place.
## Implementation
I implemented the cache path: resolving each icon from a known file or the site's declared HTML icon, fetching it server-side with a custom two-second timeout, storing it behind Presearch's domain, and enforcing mTime-based expiry with no-cache headers and scheduled memory-conscious cleanup. Tests lock the fetch, expiry, and header policy in place.
## Results
The favicon cache runs in production behind img.presearch.org, serving result-page icons from Presearch's own domain so third-party sites never see the searcher. Hotlinking's tracking leak is closed by construction, the results page no longer waits on hundreds of uncontrolled hosts, and the store stays bounded by mTime expiry plus scheduled, memory-conscious cleanup rather than growing without end.
## Takeaways
For a privacy product, third-party requests are part of the threat model. A bounded server-side cache improves privacy and resilience at the same time.