Paul Levitt

Projects  ·  Case Study

Content-Addressed Caching Strategy

Redesigned how Lifion's search authorization scaled, replacing per-user index writes with content-addressed cache keys — eliminating authorization-driven re-indexing while guaranteeing correct results on a user's first search after a bulk import.

The Problem

A user's search access was fluid — role, delegation, activity — and couldn't be computed ahead of time, only resolved at runtime. The existing design worked correctly: on each search, compute what the user could see, then stamp their ID into every visible SOLR record and field. But index writes scaled with user count, and authorization changes triggered re-indexing on nearly every query.

In practice: after a client bulk-imported 3,000–5,000 records, a practitioner searching for someone in that batch often couldn't find them for a minute or more.

The Goal

  • Decouple index-write cost from user count — remove authorization changes as a re-index trigger.
  • Guarantee a correct first search immediately after a bulk import.
  • Preserve strict per-record access control throughout.

The Approach

  • Replaced per-user SOLR index tagging with content-addressed cache keys: hashed each user's authorized record set so users sharing a permission profile share one cache entry.
  • Near-match reuse (>90% overlap) with inclusion/exclusion deltas when no exact key existed — the exclusions are the safety guarantee, ensuring reuse can never expose a record the user isn't entitled to see.
  • Fallback for a weaker match: combined keys to reach ≥70% combined overlap; if combined deltas exceeded 256 IDs, built a new hash set from the closest match.
  • Rejected sending the raw authorized-ID list per request — it hit request size limits. Hashing makes the set addressable rather than enumerable.
  • Freshness via a timestamp-delta protocol: each search sent the user's last-refresh timestamp, SOLR returned records indexed since, and a small auth query resolved just those.
  • A nightly reconciliation job rebuilt shared keys from cross-user intersections, with TTL-ahead key rotation (7-day expiry, rotated a day ahead).

Built in Node.js, and SOLR. I owned the full service design and caching algorithm; the SOLR instance itself was owned by a colleague.

The Impact

  • Guaranteed a correct first search immediately after a bulk import — closed the client-reported visibility gap (previously a minute or more).
  • Eliminated authorization-driven SOLR re-indexing on most searches.

Scope:

This addressed the authorization-driven re-index and freshness gap specifically — bulk-import latency end-to-end was a separate, already-resolved issue.