# Spaced repetition scheduler

Paste a flashcard review log and get every card's next review date, interval, ease or stability, and leech status with the SM-2 or FSRS algorithm.

## Run it

- **CLI:** `gizza tool spaced-repetition-scheduler "capital-of-peru, 2026-08-01, good
capital-of-peru, 2026-08-02, good
kanji-water, 2026-08-02, again"`
- **Web:** https://gizza.ai/tools/spaced-repetition-scheduler/
- **Agents:** machine-readable descriptor (parameters JSON Schema) at https://gizza.ai/tools/spaced-repetition-scheduler/tool.json

## Inputs

- `reviews` — Review log _(field)_
- `algorithm` — Algorithm _(field)_
- `grade_scale` — Grade scale _(field)_
- `today` — Reference date _(field)_
- `output` — Output _(field)_
- `sort` — Sort rows by _(field)_
- `only_due` — Only cards due now _(field)_
- `desired_retention` — Desired retention (FSRS) _(field)_
- `ease_start` — Starting ease (SM-2) _(field)_
- `min_ease` — Minimum ease (SM-2) _(field)_
- `first_interval` — First interval, days (SM-2) _(field)_
- `second_interval` — Second interval, days (SM-2) _(field)_
- `easy_bonus` — Easy bonus (SM-2) _(field)_
- `hard_multiplier` — Hard multiplier (SM-2) _(field)_
- `interval_modifier` — Interval modifier _(field)_
- `lapse_multiplier` — Lapse multiplier (SM-2) _(field)_
- `max_interval` — Maximum interval, days _(field)_
- `leech_threshold` — Leech threshold, lapses _(field)_
- `forecast_reviews` — Forecast reviews _(field)_
- `forecast_grade` — Assumed forecast grade _(field)_
- `fsrs_weights` — Custom FSRS weights _(field)_

## Output

- Schedule (text)

## Query parameters

Open the tool pre-filled and auto-run via URL:

- `reviews` — Review log
- `algorithm` — Algorithm
- `grade_scale` — Grade scale
- `today` — Reference date
- `output` — Output
- `sort` — Sort rows by
- `only_due` — Only cards due now
- `desired_retention` — Desired retention (FSRS)
- `ease_start` — Starting ease (SM-2)
- `min_ease` — Minimum ease (SM-2)
- `first_interval` — First interval, days (SM-2)
- `second_interval` — Second interval, days (SM-2)
- `easy_bonus` — Easy bonus (SM-2)
- `hard_multiplier` — Hard multiplier (SM-2)
- `interval_modifier` — Interval modifier
- `lapse_multiplier` — Lapse multiplier (SM-2)
- `max_interval` — Maximum interval, days
- `leech_threshold` — Leech threshold, lapses
- `forecast_reviews` — Forecast reviews
- `forecast_grade` — Assumed forecast grade
- `fsrs_weights` — Custom FSRS weights

Example: `https://gizza.ai/tools/spaced-repetition-scheduler/?reviews=capital-of-peru%2C%202026-08-01%2C%20good%0Acapital-of-peru%2C%202026-08-02%2C%20good%0Akanji-water%2C%202026-08-02%2C%20again&algorithm=sm2&grade_scale=auto&today=2026-08-24%20%28blank%20%3D%20last%20review%20in%20the%20log%29&output=table&sort=due&only_due=true&desired_retention=0.9&ease_start=2.5&min_ease=1.3&first_interval=1&second_interval=6&easy_bonus=1.3&hard_multiplier=1.2&interval_modifier=1.0&max_interval=36500&forecast_reviews=6&forecast_grade=good&fsrs_weights=0.2172%2C%201.1771%2C%203.2602%2C%20%E2%80%A6%20%2821%20numbers%2C%20blank%20%3D%20built-in%29`

---

## About this tool

Paste a flashcard review log and this tool replays each card's history to compute the next review date. It is designed for quick schedule audits: no account, no deck database, and no hidden state. Each run is deterministic, so the same rows and options produce the same due dates.

Use one row per review with a card name, a date, and a grade:

```text
card, date, grade
capital-of-peru, 2026-08-01, good
capital-of-peru, 2026-08-02, good
capital-of-peru, 2026-08-08, good
kanji-water, 2026-08-01, again
kanji-water, 2026-08-02, hard
```

Rows may be comma, tab, semicolon, pipe, or whitespace separated. Grades can be words (`again`, `hard`, `good`, `easy`), four-button numbers (`1`–`4`), or SuperMemo quality scores (`0`–`5`). A line containing only a card name declares an unreviewed card so it appears as new and due.

## Worked example

With SM-2 defaults and `today = 2026-08-24`, this input:

```text
card, date, grade
capital-of-peru, 2026-08-01, good
capital-of-peru, 2026-08-02, good
capital-of-peru, 2026-08-08, good
kanji-water, 2026-08-01, again
kanji-water, 2026-08-02, good
new-card-never-seen
```

produces a schedule table with each card's next due date, interval, days until due, repetition count, lapse count, and status. Use `output = csv` for spreadsheets, `output = json` for scripts, `output = explain` to see every state transition, or `output = forecast` to project the next reviews assuming the selected forecast grade.

## Limits and edge cases

- The run is capped at 5,000 review rows and 2,000 distinct cards.
- `today` is explicit. When it is blank, the latest review date in the log is used rather than the system clock.
- FSRS mode exposes difficulty, stability, and retrievability, and accepts a custom 21-number weight vector. It does not train or optimise weights from your history.
- There is no interval fuzz or workload balancing. This keeps output reproducible, but a real flashcard app may spread cards differently.
- Dates must be calendar dates in `YYYY-MM-DD` form. `/` and `.` separators are accepted, but ambiguous regional dates are not.

## FAQ

<details>
<summary>Which algorithm should I choose?</summary>

Choose `sm2` when you want the classic repetition/ease/interval model used by many simple flashcard schedulers. Choose `fsrs` when you want difficulty, stability, retrievability, and desired-retention controls. FSRS output is useful for comparing how the same history would schedule under a memory-model approach.

</details>

<details>
<summary>Can this import a full flashcard collection?</summary>

It imports a review log, not card fronts, answers, tags, or media. Export the columns you need as text or CSV: card identifier, review date, and grade. Optional state fields such as `ease=`, `interval=`, `reps=`, `lapses=`, `difficulty=`, `stability=`, and `last=` can be added to seed existing scheduler state.

</details>

<details>
<summary>Why do my dates differ from a flashcard app?</summary>

Apps often add interval fuzz, daily load balancing, buried siblings, deck limits, timezone rules, and version-specific scheduler tweaks. This tool intentionally computes a deterministic per-card schedule from the pasted history and parameters. Use the output as an auditable calculation, not as a full deck-sync replacement.

</details>

<details>
<summary>Does the tool train FSRS weights?</summary>

No. Training FSRS weights requires optimisation over a large history and is out of scope for a synchronous browser-local calculator. Paste a 21-number vector if you already have one; otherwise the built-in defaults are used.

</details>

## Related tools

- [Strip accents and transliterate text to plain ASCII](https://gizza.ai/tools/accent-stripper/): Paste text and strip accents to plain ASCII. Transliterate non-Latin scripts, preserve chosen characters, lowercase, and audit unmapped output.
- [Brotli Decompress](https://gizza.ai/tools/brotli-decompress/): Paste a Brotli (.br) payload as Base64 or hex and read what's inside. Output as text, hex, or Base64, with size and ratio stats. Free, private, no sign-up.
- [Child Growth Percentile Calculator](https://gizza.ai/tools/child-growth-percentile/): Compute CDC child growth-chart percentiles and z-scores from age, sex, height, weight and head circumference. Supports metric or US units.
- [Dependency Risk Auditor](https://gizza.ai/tools/dependency-risk-auditor/): Audit a package.json, package-lock.json, yarn.lock or pnpm-lock.yaml for wildcard versions, git/URL deps, install scripts and missing integrity hashes.
- [DNA / RNA Reverse Complement](https://gizza.ai/tools/dna-reverse-complement/): Reverse-complement DNA or RNA in your browser — full IUPAC ambiguity codes, FASTA records, preserved case, complement-only and reverse-only modes. No upload.
