I’m using Anki for 5 years now and still using multiple filtered decks to fullfill this.
I just want to see all my new (blue) cards before starting the red and greens. I imagine this could be a simple configuration that could be native for all PC and Android app yet it was never made.
My process today is to filter all my subdecks with “is:new” in a separated Deck and use a “rebuild all filtered decks” addon after each study section.
The logic behind it is that I’m making my own medic cards for themes I already studied. I’m not learning from 0, and I want to review all the cards at once. The blue cards “never” enter the schedule once I didn’t surpass the first red cards wave, wich isolates them from the rest. So using the filtered decks I make a “first pass” in all cards before starting review direct from the main deck, wich looks like an extra, annoying, step, especially when I’m using ankidroid, where I don’t have the addons to speed up the process.
___
I asked some IA agents to audit the code of a github’s anki copy trying to identify the root of this. I’m not dev so it was the only way I found to help. I’m sorry if the report contain any slop. (I would attach this as a file, but the forum don’t let me)
Anki
Summary
The “New/review order → Show before reviews” deck option exists and the scheduler code is correct, but in practice due reviews are consumed before new cards. Investigation of the source (tag 25.09.2, commit 3890e12) reveals the root cause is config resolution (silent fallback to MixWithReviews) compounded by a dead global preference. This post documents the issue and proposes a concrete code-level fix for the devs.
What I want
Order: all new (blue) → then reviews (red) mixed with interday learning (green), or red then green. Never green before red.
Correct config (that should produce this order)
Deck options → Display Order:
- New/review order → Show before reviews (blue first)
- Interday learning/review order → Mix with reviews (green mixed with red) or Show after reviews (red then green)
Other settings: new/day 9999, reviews/day 9999, “New cards ignore review limit” ON, FSRS active, “Review sort order: Descending retrievability”, “New card gather order: Random cards”, “New card sort order: Order gathered”.
Isolated leaf deck: 214 blue / 18 red / 21 green.
Symptom
With new_mix = BeforeReviews, the red counter (18) decreases first — due reviews are consumed before new cards. Blue cards do not appear first.
What the source says (tag 25.09.2 ≡ main 77d61d7 — logic IDENTICAL and CORRECT)
rslib/src/scheduler/queue/builder/mod.rs:266-278—merge_new()withReviewMix::BeforeReviews→SizedChain::new(new_iter, review_iter)(all new before all reviews). Correct.builder/mod.rs:251-264—merge_day_learning():Mix with reviews→Intersperser;After reviews→SizedChain(reviews, day_learning).builder/mod.rs:207—main_iter = merge_new(with_interday_learn, new, new_review_mix).builder/mod.rs:232-249—sort_options()readsconfig.inner.new_mix()fromdeck.config_id().rslib/src/scheduler/queue/mod.rs:156-161—CardQueues::iter()=intraday_now → main → intraday_ahead.- UI:
ts/routes/deck-options/DisplayOrder.svelte:158-173binds$config.newMix;choices.ts:121-136maps “Show before reviews” →BEFORE_REVIEWS.
So the config should produce blue → (red+green). My stable build (25.09.4) does not reproduce this.
Root cause (3 code-level gaps)
Gap 1 — Silent fallback to MixWithReviews
sort_options() (builder/mod.rs:232-249): when deck.config_id() is None (filtered/custom-study deck) OR the config_id is missing from config_map, it silently returns QueueSortOptions::default() → new_review_mix = MixWithReviews. No warning, no parent inheritance, no global fallback. Custom-study/filtered sessions silently ignore the per-deck “New/review order” setting.
Gap 2 — Dead global preference
proto/anki/config.proto:100-109 defines Preferences.Scheduling.new_review_mix (enum NewReviewMix { DISTRIBUTE=0; REVIEWS_FIRST=1; NEW_FIRST=2 }). rslib/src/config/mod.rs:243 has get_new_review_mix() / set_new_review_mix(). But get_new_review_mix() is ONLY called from rslib/src/preferences.rs (round-trip) — never by the scheduler. The v3 builder reads per-deck config.inner.new_mix() instead. The comment in the source says: /// 2021 scheduler moves this into deck config. So the global preference is dead code — users who set it (or migrated collections) get zero effect. There is also no UI binding for it in the Preferences screen.
Gap 3 — No order-assertion test
The existing test new_card_potentially_burying_review_card uses BeforeReviews but never asserts the queue order (new before review).
Proposed fix (code-level, for devs)
Fix A — Robust config resolution + global fallback
File: rslib/src/scheduler/queue/builder/mod.rs, sort_options() (lines 232-249).
Current:
fn sort_options(deck: &Deck, config_map: &HashMap<DeckConfigId, DeckConfig>) -> QueueSortOptions {
deck.config_id()
.and_then(|config_id| config_map.get(&config_id))
.map(|config| QueueSortOptions {
new_order: config.inner.new_card_sort_order(),
new_review_mix: config.inner.new_mix(),
// ...
})
.unwrap_or_else(|| QueueSortOptions {
new_order: NewCardSortOrder::NoSort,
..Default::default()
})
}
Proposed: add global_mix: NewReviewMix parameter; in the fallback branch, use the global preference instead of silently defaulting to MixWithReviews:
fn sort_options(
deck: &Deck,
config_map: &HashMap<DeckConfigId, DeckConfig>,
global_mix: NewReviewMix,
) -> QueueSortOptions {
deck.config_id()
.and_then(|config_id| config_map.get(&config_id))
.map(|config| QueueSortOptions {
new_order: config.inner.new_card_sort_order(),
new_review_mix: config.inner.new_mix(),
// ...
})
.unwrap_or_else(|| {
tracing::debug!(
deck_id = ?deck.id,
"deck has no resolvable config; falling back to global new/review mix"
);
QueueSortOptions {
new_order: NewCardSortOrder::NoSort,
new_review_mix: match global_mix {
NewReviewMix::Mix => ReviewMix::MixWithReviews,
NewReviewMix::ReviewsFirst => ReviewMix::AfterReviews,
NewReviewMix::NewFirst => ReviewMix::BeforeReviews,
},
..Default::default()
}
})
}
Call site in QueueBuilder::new (line ~149): thread the global preference:
let sort_options = sort_options(&root_deck, &config_map, col.get_new_review_mix());
Fix 2 — Wire the global preference into the scheduler
File: rslib/src/scheduler/queue/builder/mod.rs, QueueBuilder::new (lines 130-187).
Add global_new_mix to the Context struct and thread it into sort_options(). This makes the legacy Preferences.Scheduling.new_review_mix a real global default for decks without a resolvable preset (or as an override — design decision for the devs: fallback-only vs. global override).
Optionally expose it in the TS Preferences UI (bind newReviewMix) so users can set “new before reviews” once for all decks.
Fix 3 — Add order-assertion test
File: rslib/src/scheduler/queue/builder/mod.rs (test module).
#[test]
fn new_before_reviews_order() {
let mut col = Collection::new();
// Add 1 new card + 1 due review card
CardAdder::new().siblings(2).due_dates(["0"]).add(&mut col);
col.update_default_deck_config(|c| c.new_mix = ReviewMix::BeforeReviews as i32);
let q = col.build_queues(DeckId(1)).unwrap();
let kinds: Vec<_> = q.iter().map(|e| e.kind()).collect();
assert_eq!(kinds, vec![QueueEntryKind::New, QueueEntryKind::Review]);
}
#[test]
fn fallback_uses_global_new_review_mix() {
let mut col = Collection::new();
col.set_new_review_mix(NewReviewMix::NewFirst);
// Deck with config_id pointing to a missing config
let q = col.build_queues(DeckId(1)).unwrap();
let sort = q.sort_options();
assert_eq!(sort.new_review_mix, ReviewMix::BeforeReviews);
}
Notes
- Deck options Display Order applies to the selected deck only, not subdecks (see
deck-config-display-order-will-use-current-deck). - Review sort order (due-date, intervals, ease, retrievability…) is a separate, orthogonal setting.
- Intraday learning (in-progress green cards) always precedes the main queue (
queue/mod.rs:156-161) — this is by design and not controllable via any setting (except burying).
Environment
- Anki 25.09.4 (d52ca669), Python 3.13.5, Qt 6.9.1, Chromium 122
- FSRS active, desired retention 82%
- Preset “UNLP_Estudando” shared by 690 decks