As someone who uses Anki extensively for medical studies, I’ve always been fascinated by the algorithms that power spaced repetition. When the FSRS (Free Spaced Repetition Scheduler) algorithm emerged as a more accurate alternative to Anki’s traditional SM-2, I wanted to bring its power to the R ecosystem for research and analysis.
The result is rfsrs — R bindings for the fsrs-rs Rust library, now available on r-universe.
install.packages("rfsrs", repos = "https://chrislongros.r-universe.dev")
What is FSRS?
FSRS is a modern spaced repetition algorithm developed by Jarrett Ye that models memory more accurately than traditional algorithms. It’s based on the DSR (Difficulty, Stability, Retrievability) model of memory:
- Stability — How long a memory will last (in days) before dropping to 90% retrievability
- Difficulty — How hard the material is to learn (affects stability growth)
- Retrievability — The probability of recalling the memory at any given time
FSRS-6, the latest version, uses 21 optimizable parameters that can be trained on your personal review history to predict optimal review intervals with remarkable accuracy.
The Rating Scale
FSRS uses a simple 4-point rating scale after each review:
Why Rust + R?
The reference implementation of FSRS is written in Rust (fsrs-rs), which provides excellent performance and memory safety. Rather than rewriting the algorithm in R, I used rextendr to create native R bindings to the Rust library.
This approach offers several advantages:
- Performance — Native Rust speed for computationally intensive operations
- Correctness — Uses the official, well-tested implementation
- Maintainability — Updates to fsrs-rs can be easily incorporated
- Type Safety — Rust’s compiler catches errors at build time
Architecture
Here’s how rfsrs connects R to the Rust library:
Usage Examples
Getting Started
library(rfsrs)
# Get the 21 default FSRS-6 parameters
params <- fsrs_default_parameters()
# Create initial memory state (rating: Good)
state <- fsrs_initial_state(rating = 3)
# $stability: 2.3065
# $difficulty: 2.118104
Tracking Memory Decay
# How well will you remember?
for (days in c(1, 7, 30, 90)) {
r <- fsrs_retrievability(state$stability, days)
cat(sprintf("Day %2d: %.1f%%\n", days, r * 100))
}
# Day 1: 95.3%
# Day 7: 76.4%
# Day 30: 49.7%
# Day 90: 26.5%
Use Cases for R
- Research — Analyze spaced repetition data with R’s statistical tools
- Visualization — Plot memory decay curves with ggplot2
- Integration with ankiR — Combine with ankiR to analyze your Anki collection
- Custom schedulers — Build spaced repetition apps in R/Shiny
Building Rust + R Packages
The rextendr workflow:
- Create package with
usethis::create_package() - Run
rextendr::use_extendr() - Write Rust with
#[extendr]macros - Run
rextendr::document() - Build and check
Resources
- rfsrs on r-universe
- rfsrs on GitHub
- fsrs-rs — The Rust library
- ABC of FSRS — Algorithm intro
- rextendr — R + Rust bindings
What’s Next
Future plans include parameter optimization (training on your review history), batch processing, and tighter ankiR integration.
If you’re interested in spaced repetition or memory research, give rfsrs a try. Feedback welcome!




