Two major releases of rfsrs are now available, bringing custom parameter support, SM-2 migration tools, and — the big one — parameter optimization. You can now train personalized FSRS parameters directly from your Anki review history using R.
Version 0.2.0: Custom Parameters & SM-2 Migration
Critical Bug Fix
Version 0.1.0 had a critical bug: custom parameters were silently ignored. The Scheduler stored your parameters but all Rust calls used the defaults. This is now fixed — your custom parameters actually work.
New Features in 0.2.0
Preview All Rating Outcomes
fsrs_repeat() returns all four rating outcomes (Again/Hard/Good/Easy) in a single call, matching the py-fsrs API:
# See all outcomes at onceoutcomes <- fsrs_repeat( stability = 10, difficulty = 5, elapsed_days = 5, desired_retention = 0.9)outcomes$good$stability # 15.2outcomes$good$interval # 12 daysoutcomes$again$stability # 3.1
SM-2 Migration
Migrating from Anki’s default algorithm? fsrs_from_sm2() converts your existing ease factors and intervals to FSRS memory states:
# Convert SM-2 state to FSRSstate <- fsrs_from_sm2( ease_factor = 2.5, interval = 30, sm2_retention = 0.9)state$stability # ~30 daysstate$difficulty # ~5
Compute State from Review History
fsrs_memory_state() replays a sequence of reviews to compute the current memory state:
# Replay review historystate <- fsrs_memory_state( ratings = c(3, 3, 4, 3), # Good, Good, Easy, Good delta_ts = c(0, 1, 3, 7) # Days since previous review)state$stabilitystate$difficulty
Vectorized Operations
fsrs_retrievability_vec() efficiently calculates recall probability for large datasets:
# Calculate retrievability for 10,000 cardsretrievability <- fsrs_retrievability_vec( stability = cards$stability, elapsed_days = cards$days_since_review)
Scheduler Improvements
Scheduler$preview_card()— see all outcomes without modifying the cardCard$clone_card()— deep copy a card for simulationsfsrs_simulate()— convenience function for learning simulations- State transitions now correctly match py-fsrs/rs-fsrs behavior
Version 0.3.0: Parameter Optimizer
The most requested feature: train your own FSRS parameters from your review history.
Why Optimize?
FSRS uses 21 parameters to predict when you’ll forget a card. The defaults work well for most people, but training custom parameters on your review history can improve scheduling accuracy by 10-30%.
New Functions in 0.3.0
fsrs_optimize()— Train custom parameters from your review historyfsrs_evaluate()— Measure how well parameters predict your memoryfsrs_anki_to_reviews()— Convert Anki’s revlog format for optimization
Optimize Your Parameters
Here’s how to train parameters using your Anki collection:
library(rfsrs)library(ankiR)# Get your review historyrevlog <- anki_revlog()# Convert to FSRS formatreviews <- fsrs_anki_to_reviews(revlog, min_reviews = 3)# Train your parameters (~1 minute)result <- fsrs_optimize(reviews)# Your personalized 21 parametersprint(result$parameters)# Use them with the Schedulerscheduler <- Scheduler$new( parameters = result$parameters, desired_retention = 0.9)
How It Works
The optimizer uses machine learning (via the burn framework in Rust) to find parameters that best predict your actual recall patterns. It analyzes your review history to learn:
- How quickly you initially learn new cards
- How your memory decays over time
- How different ratings (Again/Hard/Good/Easy) affect retention
I tested it on my own collection with ~116,000 reviews across 5,800 cards — optimization took about 60 seconds.
Compare Parameters
Evaluate how well different parameters predict your memory:
# Compare default vs optimizeddefault_metrics <- fsrs_evaluate(reviews, NULL)custom_metrics <- fsrs_evaluate(reviews, result$parameters)cat("Default RMSE:", default_metrics$rmse_bins, "\n")cat("Custom RMSE:", custom_metrics$rmse_bins, "\n")
Lower RMSE means better predictions.
Bug Fix
Fixed an issue where cards with only same-day reviews (all delta_t = 0) could cause the optimizer to fail. These are now correctly filtered out.
Installation
# From r-universe (recommended)install.packages("rfsrs", repos = "https://chrislongros.r-universe.dev")# Or from GitHubremotes::install_github("open-spaced-repetition/r-fsrs")
Note: First build of v0.3.0 takes ~2 minutes due to compiling the ML framework. Subsequent builds are cached.
Full API Summary
| Function | Description | Version |
|---|---|---|
fsrs_optimize() | Train custom parameters | 0.3.0 |
fsrs_evaluate() | Evaluate parameter accuracy | 0.3.0 |
fsrs_anki_to_reviews() | Convert Anki revlog | 0.3.0 |
fsrs_repeat() | All 4 rating outcomes at once | 0.2.0 |
fsrs_from_sm2() | Convert from SM-2/Anki default | 0.2.0 |
fsrs_memory_state() | Compute state from review history | 0.2.0 |
fsrs_retrievability_vec() | Vectorized retrievability | 0.2.0 |
Scheduler$preview_card() | Preview outcomes without modifying | 0.2.0 |
Card$clone_card() | Deep copy a card | 0.2.0 |
Links
Feedback and contributions welcome!














