As a student, I never imagined I’d be the one implementing a feature designed to prevent cheating — but here we are!
At Avanti Fellows, I along with recently introduced Shuffle Question Ordering in quizzes to ensure fairness in online assessments. Here’s why this matters and how it works —
Why Shuffle Questions?
In an online setup, students taking the same test at the same time could easily share answers if questions appeared in the same order. Randomizing the sequence makes it harder to copy, ensuring a fairer assessment.
But there’s a catch within the system - it’s not pretty straight forward:
We load questions in small batches, not all at once, to keep the system fast. So we will shuffle within this small buckets( batches of size 10 default)
[0,1,2,3,4…..9] => we will be randomizing in this block of questions only ensuring that questions are fetched.
Some quizzes have different sets of questions that get shuffled randomly, which can mix up the topics.
The order of questions must stay the same, even if a student returns to the test later.
This ensures students can navigate the questions easily and have a smooth experience.
Exception: OMR Assessments
All the OMR assessments will have no effect as there is no need in shuffling of questions except OMR assesments we can find shuffling in all the other assessment types.
How Does It Work?
Instead of scrambling questions in a way that could break the test, we assign a hidden randomized order when a student starts the quiz.
Note: We will be following a 0-based indexing while accessing we use this and while displaying question-1 we go the index 0.
Example:
Imagine a quiz with 5 questions:
Normally:
Q0, Q1, Q2, Q3, Q4Shuffled:
Q4, Q1, Q0, Q2, Q3
Now, when the student sees:
“Question 1”, they’re actually seeing Q4(last question in the normal order).
“Question 2”, they’re seeing Q1(second question in the normal order), and so on.
But behind the scenes:
Answers are saved in their original positions to avoid confusion.
If a student leaves and comes back, their shuffled order stays the same.
Edge Case: When the size of the question set exceeds the bucket size (10)
In this scenario, the question set will be divided into smaller chunks (buckets) of size 10. If the total number of questions isn’t a multiple of 10, the last bucket will contain the remaining questions.
For example, if there are 25 questions in the question set:
The questions will be grouped as [0–9], [10–19], and [20–24].
Each bucket is shuffled individually.
Handling previous sessions without question_order
To address previous sessions where the question_order field was missing in the database, we added a backend script that assigns a linear ordering to the questions (from 0 to total_questions - 1). This ensures consistency across all sessions—both old and new.
Stability Through Testing
We implemented comprehensive unit and end-to-end (E2E) tests to verify that the new functionality works as intended. These tests confirm that:
The new feature correctly assigns a question order.
Existing features remain stable and unaffected.
Development References
Frontend Implementation: Shuffle Question Order UI Handling
Implements the shuffled view logic and ensures question order is preserved across sessions.
Backend Logic & Persistence: Assign and Store Shuffled Order
Handles bucket-based shuffling and stores randomized question order on the first session of a non-OMR assessment.
Wrapping It Up
This has been a meaningful journey for me. There were moments when I felt it might not come together, but seeing the feature go from planning to development to thorough testing has been incredibly rewarding. Knowing that this project directly benefits students makes the experience even more fulfilling.
I’d like to express my sincere gratitude to
for his unwavering support and motivation. Without him, I might have completed the development but wouldn’t have gained such a deep understanding of the entire process.If you spot any errors, have suggestions for improvements, or wish to contribute to our repositories, please reach out to us on Avanti’s Discord channel.



This is super! Thanks for working on this important piece of the stack :)