Skip to content
Doppel
Home

Watch it run cold

The rest of this site serves savedruns, for speed and safety. This page is the other half of the proof: the engine running live. A warm ~12 second answer, the ~12 minute cold path and why it’s capped by design, and the cache trick that lets both coexist. It runs against the real backend over an SSH tunnel (never linked from this site or exposed to the internet), walked through act by act below.

same code path · two latencies
warm · cache hit
~12 s

The median latency across the saved runs. Every candidate is already in the pgvector cache, so the run skips embedding entirely.

cold · cache miss
~12 min

701 s end-to-end in prod. The ARQ worker grinds MusicBrainz at ~1 req/s, capped at ~75×7s by the resolve limit (WORKER_MAX_JOBS=1; the work is I/O-bound, so concurrency would only multiply latency).

One run_pipeline coroutine serves both. The only difference is how many candidates miss the cache. The ~12 min above is the full 75-candidate production run; the recorded cold replay below is a shorter capture of the same shape (~3 min, 60 uncached candidates). Replay the Gate-1-cold Jolene capture

What the run shows

The live run, act by act, driven against the real backend over an SSH tunnel. It’s the same sequence the saved replays animate from persisted telemetry.

  1. Act 1

    It's live

    • POST /recommend with Take Five by The Dave Brubeck Quartet against a warm corpus returns a 200 in about 12 seconds.
    • The top neighbours are real: Alphanumeric by Lee Konitz, Red Pepper Blues by Art Pepper, Three to Get Ready by Dave Brubeck.
    • Note that the seed's own studio master never appears. A near-duplicate of the seed (audio ≥ 0.98 and a title-token match) is suppressed, so the engine never recommends the song back to itself, while a live or acoustic take, which scores lower, survives.
  2. Act 2

    The cold cliff is real, and it's on purpose

    • POST a never-seen seed and the API returns 202 JobAccepted with a queued job handle and a status URL, rather than blocking the request. That's Gate 1: at 5 or more uncached candidate lookups (the ones that hit MusicBrainz at ~1 req/s), resolution is deferred to the async worker up front.
    • The whole cold request took about 701 seconds (~12 minutes) end to end in production. Most of that is the ARQ worker grinding MusicBrainz at roughly one request a second, about 7 seconds per candidate. It's bounded on purpose: RESOLVE_CANDIDATE_LIMIT=75 caps the resolve at ~75×7s ≈ 9 minutes (embedding, scoring, and the rationale make up the rest), and WORKER_MAX_JOBS=1 because cold work is MusicBrainz-bound, so concurrency would buy no throughput, only multiply latency.
    • Polling the status URL returns 202 while it runs, then flips to 200 with the full recommendation response, degradation block and all. The job handle is a plain sequential id. Non-enumerable tokens and auth are a named, deferred item, not a gap being hidden (it's why there's no public live endpoint).
    • Re-run the exact same seed and it returns a warm 200 in ~12 seconds, now with a high embeddings-cache-hit count. That's the lazy-corpus payoff: the first run grew the pgvector cache, so the second skips the embedding work entirely.
  3. Act 3

    Why it's built this way

    • The pivots: an LLM can't judge audio it never heard (and Spotify closed those endpoints to new apps in 2024), and a pre-embedded royalty-free corpus answers a chart hit with unknown tracks. The hybrid retrieve-then-rerank design is what survived. CLAP owns ranking, the LLM only explains.
    • Open the eval reports and walk the ablation: at the resolve cap of 75, the CLAP-reranked top-10 shares a median of just 0.2 of its order with the pure cultural ranking, moving tracks a median of 3.4 places. The audio leg is doing real work, not passing the cultural order through.
    • Open the Postgres query_logs / query_log_results row backing that poll: the durable, dual-persisted telemetry that the static showcase JSON is a serialization of. Same numbers, live source of truth.
    • Honest closer: Doppel won't beat Spotify for casual 'play me something similar.' The wedge is deliberate discovery, and the deferred hardening (auth, rate limiting, opaque handles, connection-scoping) is scoped engineering judgment, named not hidden.

Want the reasoning rather than the runtime? How it works covers the design, the pipeline, and the eval evidence.