Delta Algorithm

How PolyCLI detects what changed and avoids re-translating unchanged content.

Why it matters

Sending your entire localisation file to provider on every run would be expensive and slow. The delta algorithm means you only pay for strings that are genuinely new or modified. On a large project with thousands of keys, a typical commit touches fewer than 20 — and only those 20 consume credits.

JSON delta

After each successful run, PolyCLI saves the source JSON as a lockfile at <localesPath>/.translator-lock.json. On the next run, it compares the current source against the lockfile recursively. Only keys whose values differ (or are new) are included in the delta.

.translator-lock.json (after first run)
{
  "greeting": "Hello",
  "nav": { "home": "Home", "about": "About" }
}
locales/en.json (second run — you added a key)
{
  "greeting": "Hello",
  "nav": { "home": "Home", "about": "About", "blog": "Blog" }
}
Delta sent to API
{
  "nav": { "blog": "Blog" }
}

Only nav.blog is translated. One word. One credit.

Markdown delta

Markdown files are split into logical blocks (paragraphs, headings, lists, blockquotes). Each block is then further split into sentence-level units:

  • Headings — treated as a single unit
  • List items / blockquotes — one unit per line
  • Paragraphs — split on sentence-ending punctuation (.!?) followed by a capital letter

Each sentence is hashed with SHA-256 (truncated to 16 hex characters). The cache stores a hash → translatedText map per language. Only sentences whose hash is absent from the cache are sent to the API — even when the surrounding paragraph changes.

Sentence-level delta example
# Paragraph with 3 sentences (first run — all 3 are new)
"The API is fast. It handles JSON and Markdown. Setup takes one minute."

Sentences sent:
  "The API is fast."              → hash: "a1b2c3d4e5f67890"
  "It handles JSON and Markdown." → hash: "b2c3d4e5f6789011"
  "Setup takes one minute."       → hash: "c3d4e5f678901122"

# Second run — only the second sentence changed
"The API is fast. It handles JSON, Markdown and YAML. Setup takes one minute."

Sentences sent:
  "The API is fast."                       ← cached, skip
  "It handles JSON, Markdown and YAML."    → hash: "d4e5f67890112233"  ← new, translate
  "Setup takes one minute."               ← cached, skip

Credits charged: ~7 words instead of ~19
Commit both .translator-lock.json and .polycli-md-cache.json to version control. If these files are missing or gitignored, PolyCLI treats every string as new and re-translates everything from scratch on each run.