Skip to content

Case study: systems architecture

Intelligent restaurant search

Conversational discovery with explicit routing, predictable AI unit economics, and latency targets suitable for high-volume production traffic.

Multi-tenant microservice, tiered search, observable by design

Case study visual for AI-assisted restaurant search and discovery product
System overviewProduction posture
Case study visual for AI-assisted restaurant search and discovery product

Executive summary

We delivered a multi-tenant restaurant discovery microservice that resolves natural-language queries (for example, “cozy Italian place for date night”) while keeping the majority of requests on a sub-100ms pathshipped. The architecture caps model spend at roughly $0.001 per AI-assisted query on averagetarget, combines Redis caching with deterministic lane selection, and ships with the metrics, logging, and guardrails operators expect in production.

Service commitments

Latency, cost, isolation, and operations

  • <100msshipped

    Search SLA

    ~80% of queriestarget hit the fast lane

  • ~$0.001target

    Avg. cost / AI search

    Budgeted hybrid retrieval

  • Multi-tenant

    Postgres RLS

    Isolated rows per tenant

  • Observable

    Production-ready

    Metrics, logs, safe limits

Three-lane search architecture

Each query is classified before any paid inference: deterministic paths carry the bulk of volume; models run only when phrasing requires interpretation; a short-TTL cache reduces repeat load on the database and providers.

  • 1~80% of traffictarget, <80mstarget

    Keyword search

    Simple intents, zero AI spend.

    • Queries like “Italian”, “sushi”, “pizza”.
    • PostgreSQL ILIKE plus PostGIS geo filters.
    • Predictable path—no model calls.

    $0 marginal cost per queryshipped

  • 2~20% of traffictarget, <1200mstarget

    Natural language AI search

    Complex intent → structured retrieval.

    • Examples: “romantic spot with live music near me”.
    • Claude Haiku parses intent to structured JSON.
    • OpenAI embeddings + pgvector cosine similarity in Postgres.

    ~$0.001 per search (budgeted)target

  • 3Hot paths, <15mstarget

    Result cache

    Repeat demand disappears at the edge.

    • Redis with 30s TTL on hashed keys.
    • Key = tenant + query + geo + filters + classification.
    • Hit-rate goal 30–40%target to protect DB and models.

Technical stack

Implementation stack

Backend

  • NestJS 10
  • TypeScript (strict)
  • DDD + Hexagonal + CQRS

Data

  • PostgreSQL 17
  • PostGIS
  • pgvector
  • Row-level security (tenancy)

Cache & realtime

  • Redis 7 — result cache (30s)
  • Semantic intent cache (60s)
  • LLM rate limits (100/min/tenant)
  • Pulse: WebSocket + Redis pub/sub

AI services

  • Claude Haiku 4.5 — intent parsing (~90% of AI callsshipped)
  • Claude Sonnet 4.6 — menu Q&A only
  • OpenAI text-embedding-3-small (1536-d)

Bounded contexts

Partitioning for maintainable evolution

Five bounded contexts share a small kernel so search behavior can evolve without coupling unrelated concerns or destabilizing shared infrastructure.

Engineering patterns

  • Domain-Driven Design
  • Hexagonal architecture
  • CQRS
  • Event-driven architecture

Tenancy

Configuration per brand

  • Valid vibes, cuisines, ranker weights, embedding templates.
  • In-memory registry with Redis warmup.

Indexing

Fresh vectors & listings

  • Venue CRUD on the search index.
  • Embedding saga on EntityIndexedEvent.

GoldenKeys

Smart filter chips

  • Auto-generated chips like “Rooftop”, “Live music”.
  • Cron every 6h from search analytics.

Pulse

Live venue status

  • Open/busy/wait signals.
  • Gateway on /pulse with WebSocket fan-out.

Shared kernel

  • TenantId & Geo value objects
  • Result<T, E> for explicit failures
  • Prisma + Redis services
  • TenantContext via AsyncLocalStorage
  • Pino logging
  • Claude & OpenAI adapters

If you are evaluating search, ranking, or multi-tenant isolation under cost and latency constraints, we can walk through a comparable architecture and delivery approach on a short call.

Discuss a similar engagementBook a technical call