---
title: "How mdfy keeps your docs, bundles, and hub fresh"
url: https://memory.wiki/RUMdz2fQ
updated: 2026-05-19T07:31:44.356Z
source: "mcp"
---
# How mdfy keeps your docs, bundles, and hub fresh

Every mdfy URL is built to be **what the AI reads when you paste it**. That promise breaks the moment your URL is showing stale content — so freshness isn't an afterthought, it's part of the deal.

This is the full picture: what's guaranteed up-to-date, what isn't, and when to click **Re-analyze**.

## TL;DR

| Layer | What | How fresh | Anything to click? |
| --- | --- | --- | --- |
| **Document body** | The markdown you wrote | Always — within ~60 seconds of save | Nothing. Just save. |
| **Bundle graph** | AI-generated themes / insights | Up-to-date until a member doc's content changes | "Re-analyze with AI" in the bundle header when stale |
| **Hub concept index** | Cross-doc "related concepts" map | Auto-extracted within seconds of each save, but 30-min cooldown per doc | "Re-analyze (N)" banner appears when stale |

Body markdown is always fresh. The AI-derived layers (bundle graph, hub concept index) sometimes need a nudge.

## Three layers, three different stories

### 1. Document body — always fresh

When you save a doc (autosave or explicit), the new markdown is in Postgres immediately. The next AI fetch sees it within ~60 seconds:

- `/raw/{id}` and `/d/{id}` always read straight from the database.
- The edge cache (`stale-while-revalidate=300`) keeps repeat requests cheap, but the moment your content changes any subsequent fetch revalidates in the background.
- Net effect: **your last save propagates to AI URLs within roughly a minute.** No action needed.

### 2. Bundle graph — Re-analyze when content drifts

A bundle's "AI graph" (themes, insights, the spatial layout of the canvas) is **generated once, then reused**. Specifically:

- The graph is computed by an LLM pass over the member docs at one moment in time.
- That moment is stamped on the bundle as `graph_generated_at`.
- mdfy compares this against the latest `embedding_updated_at` across the member docs (which only bumps when a doc's actual content hash changes).

If a member doc's content has changed since the graph was generated, the bundle is **stale**. You'll see:

- A subtle "Re-analyze with AI" refresh icon in the bundle header — click it any time.
- The graph view itself indicates the stale state.

Why not auto-rebuild? Bundle graphs cost a real LLM call and the user is usually in the middle of editing — auto-triggering wastes tokens and disrupts focus. **You decide when the analysis is worth re-running.**

### 3. Hub concept index — automatic + manual top-up

The hub's `concept_index` (what AIs see as "the user's knowledge graph") is the most complex. Every doc you save fires this pipeline:

1. **Enqueue** an ontology refresh job (deduplicated at the database level — bursts of saves don't pile up).
2. **Fast-path run** inside Vercel's `after()` closure → the LLM extraction usually finishes within a few seconds.
3. **Backstop** — if the serverless instance dies mid-flight, a cron worker picks up the pending row and retries.

So normal usage: concept changes appear in the hub URL **within seconds** of saving.

#### Two automatic guardrails that can make a doc look stale

1. **30-minute per-doc cooldown** — back-to-back edits on the same doc don't re-run the LLM extractor. Without this, an active editing session would burn tokens on every keystroke.
2. **200-character minimum delta** — trivial edits (a typo fix) don't trigger re-extraction.

These keep cost predictable, but they mean that within a heavy editing session your doc's concept attribution may lag the actual content for a while.

#### The Re-analyze banner

When the hub view opens, mdfy checks:

- `concepts_built_at` = the most recent successful ontology job's finish time
- `docs_touched_at` = the latest `embedding_updated_at` across your docs

If `docs_touched_at > concepts_built_at`, you see:

> 🟡 **Concepts out of date** · N docs have changed since the last build
> [Re-analyze (N)]

Clicking **Re-analyze**:

- **Only re-extracts the N docs that actually changed** — unchanged docs are skipped entirely.
- **Caps at 50 docs per click.** If you have more stale docs, the extras stay queued and the cron worker processes them in the background over the next few minutes.
- **Bypasses the 30-minute cooldown** — that's the whole point of an explicit click.
- Fires asynchronously — the button label flips to "Re-analyzing…" while the queue drains, but you can keep working.

So a Re-analyze click is cheap: at most 50 short LLM calls for the docs that genuinely changed. Not "rebuild the whole hub from scratch."

## Doc-level Re-analyze

You can also force a single doc's concepts to refresh — right-click any doc in the sidebar and choose **Re-analyze concepts**. Same machinery as the hub-wide button, scoped to one doc, bypasses the cooldown. Useful when:

- You're polishing a doc in tight cycles and want the hub's concept attribution to keep up.
- A doc's concept tags look obviously off — force a re-extraction.

## When you DON'T need to click anything

- You edited a doc and shared its URL. The receiving AI will see your edits within ~60 seconds. Concept attribution catches up in seconds-to-minutes automatically.
- You haven't touched the hub layer (just reading existing docs). Nothing to refresh.
- You're an anonymous (non-signed-in) user — no concept index applies.

## When clicking Re-analyze is worth it

- You bulk-imported or edited multiple docs and want the hub's concept map to reflect the new shape **immediately**.
- The yellow banner appears and you're about to share your hub URL with an AI.
- You added a doc on a new topic and want it surfaced as "related" to existing docs right away.

## Why we don't auto-rebuild more aggressively

Two reasons:

1. **Cost discipline.** Concept extraction is a Haiku call per doc. Auto-rebuilding on every save would burn tokens during noisy editing sessions where the user doesn't care yet.
2. **Predictability.** When something changes in your hub, you're the one who chose for it to change. Implicit background rebuilds make "why does my AI see X?" much harder to debug.

The trade is: body markdown gets aggressive freshness guarantees (always-fresh, no click needed). AI-derived metadata gets fast-but-not-instant defaults with explicit override available.

---

*Last updated 2026-05-19 · part of [mdfy.app](https://mdfy.app)'s public documentation.*
