Overview

The Master Schedule Optimizer reads your school's current schedule and student course requests directly from Aeries exports and uses a mathematical constraint solver to build a new master schedule that fills as many student requests as possible — while respecting your constraints. No AI or machine learning is involved.

Upload two files, answer a short configuration wizard, and the system produces an optimized schedule ready to load back into Aeries.

The Two Input Files

MST / SMS File

The Master Schedule export from Aeries. Contains every section — section number, period, teacher, course, room, and enrollment cap.

SSS File

The Student Subject Selections export. Lists every course request each student has made for the upcoming school year.

The Workflow at a Glance

1 Upload
→
2 Configure Wizard
→
3 Optimizer Runs
→
4 Review Results
→
5 Export

After reviewing results you can bump section capacities, assign teachers to high-demand courses, or adjust any constraint and re-run the optimizer without re-uploading your files.

1 Upload Files

The home page is where every session begins. Upload both Aeries export files to start the analysis. Both .xlsx and .csv formats are accepted.

HOW THIS WORKS
No AI involved
Mathematical constraint solving, not machine learning.
No student PII
Files contain section numbers and course codes only.
Master Schedule Optimizer for Aeries® SIS
Turn weeks of scheduling headaches into 10 minutes of optimization
1
Upload
2
Profile
3
Configure
4
Optimize
5
Export
MST / SMS File *
⊞
Master Schedule Table
Drag & drop or click to browse
.xlsx or .csv
SSS File *
👥
Student Scheduling Schedules
Drag & drop or click to browse
.xlsx or .csv
🔍 Analyze Schedule
Takes 5–20 seconds depending on file size.
🛡 Processed locally — no data sent externally ⚡ Supports Aeries SIS exports 2020 onward 🔄 Sessions saved 24 hrs — re-upload anytime
💡Sessions are saved for 24 hours. If you need to step away after uploading, you can return to the wizard or results page without re-uploading your files.

Period Setup

After your files are analyzed you move through the 5-step workflow. Step 3 is the Configuration Wizard — a single scrollable page with numbered sections. A navy sidebar on the left shows your progress and lets you jump between sections.

Section 1 — Period Configuration lets you confirm which periods are part of the standard school day. The system auto-detects standard vs. outlier periods from your MST data.

CONFIGURATION WIZARD
✅
Period Setup
Standard & outlier periods
✅
Section Locks
Pin sections in place
✅
Teacher Loads
2 above standard
✅
Missing Courses
4 courses need action
✓
Staff Changes
✓
Solver Settings
Step 3 of 5
Configure Optimization Constraints
Review the detected anomalies and tell the optimizer how to handle each one.
1
Period Configuration
Confirm which periods are standard scheduling periods. Outlier periods require a handling decision.
Standard Scheduling Periods Check all periods that are standard instructional periods
0
1
2
3
4
5
6
7
ℹ Detected standard periods: 1, 2, 3, 4, 5, 6. Outlier periods detected: 0, 7. The optimizer will only assign students to checked periods.
✓ All sections complete — ready to optimize!
← Back to Profile
Save & Run Optimizer →

Periods shown in blue are active (checked). Gray buttons are outlier periods. The optimizer only moves and places students in checked periods — sections in unchecked periods stay exactly where they are.

💡Leave Period 0 (zero period / early-bird) unchecked unless you want the optimizer to treat it as a normal rotation period. Individual sections in outlier periods can still be pinned in the Section Locks step.

Section Locks

Section 2 — Pin / Lock Specific Sections — tells the optimizer which sections must not be moved. Outlier-period sections are locked by default. Standard-period sections are unlocked by default.

Click the ∨ chevron on any period row to expand it and see individual sections. Toggle each section's lock state by clicking its checkbox.

2
Pin / Lock Specific Sections
Locked sections will not be moved or changed by the optimizer. Lock sections that have contractual, room, or teacher constraints.
📌 28 outlier-period sections found. All are locked by default. Expand a period to review its sections and unlock any you want the optimizer to consider for rescheduling.
P0Period 01 section
🔒 1 locked∨
P7Period 727 sections
🔒 27 locked∨
Pin Standard-Period Sections All unlocked by default — expand a period to lock specific sections.
P1Period 129 sections
0 locked∨
P2Period 231 sections
0 locked∨
Manually Add a Section — Add a section not yet in the MST. The optimizer will treat it as a real section.
Course Number
E.G. P730
Period
— Select —
Teacher
— Select —
⊕ Add Section
⚠️Locking too many sections limits the optimizer's ability to improve the schedule. Lock only what truly cannot move — special education rooms, co-teaching assignments, contractual commitments, etc.

Teacher Loads

Section 3 — Teacher Section Load — is a read-only reference panel. It flags any teachers whose current section count is above the standard load for your school, so you're aware of anomalies before the optimizer runs. No action is required here.

3
Teacher Section Load
Standard load is 6 periods. The 2 teachers below carry above-standard loads. This panel is for reference — the optimizer works within the existing schedule.
ℹ For reference only. After running the optimizer, use the Staffing Gap Matchmaker on the Results page to act on teacher availability.
Cipolla Gregory #83
7 periods (+1 above standard)242 students · 7 sections›
Fernandez Kori #2
7 periods (+1 above standard)63 students · 9 sections›

Click the › chevron to expand a teacher's section list. This step is informational — if a teacher is overloaded, address it through staffing decisions outside the optimizer before the final export.

Resolve Missing Courses

Section 4 — Resolve Missing Courses — lists every course that appears in student SSS requests but has no sections in the current MST. You must choose an action for each course before you can run the optimizer.

4
Resolve Missing Courses
These 4 courses have student requests but no sections in the MST. Choose an action for each. All are HIGH severity.
0808 Career Foc Med LOW
👥 27 student requests ⊞ -2 sections needed No action selected
+
Create Sections
⇄
Map to Existing
✕
Exclude
🗓
Hold Period
M120 Mixed Choir LOW
👥 8 student requests
+
Create Sections
⇄
Map to Existing
✕
Exclude
🗓
Hold Period

The Four Options

OptionWhat it doesWhen to use
Create SectionsThe optimizer builds new sections and places students into them. You choose how many sections and which periods to allow, and optionally a preferred teacher (existing teacher or a New Hire reserved in the 99001+ range), grade level range (Low/High — blank defaults to 9–12), and classroom size (Max capacity — blank uses the wizard's class-cap default).Course is being offered but isn't in the MST yet.
Map to ExistingRequests for this course are treated as requests for a different, existing course.Course was renamed or renumbered in Aeries.
ExcludeRequests are ignored — students requesting this course won't be scheduled for it.Course is not being offered; requests were submitted in error.
Hold PeriodCreates a placeholder section pinned to a specific period.Course is planned but teacher isn't confirmed yet.
💡When choosing Create Sections, the optional fields beneath the periods (Preferred Teacher, Grade Level, Classroom Size) all default to blank — leave them alone and the optimizer assigns sensible values. Fill them in only when you have a specific request for the new sections.

Solver Settings

Section 5 — Solver Settings — lets you tune how the optimizer runs. The defaults work well for most schools. Only adjust these if you have a specific reason to.

5
Solver Settings
Tune the optimizer parameters. Defaults are recommended for most schedules.
Solver Time Limit (seconds)
120s
Longer limits allow better solutions. 120–180s recommended for schedules with 200+ sections.
Target Minimum Fill Rate
75%
Current average fill rate is 75.3%. Set target above current to push for improvement.
Period Rearrangement (Phase 2)
Enable period rearrangement
Unlocked sections may shift to a different standard period. Sections taught by the same teacher move together as a group.
Course Priority Weights
Mark courses as High Priority (weight 10×) so the solver fills them before lower-priority courses when capacity forces a choice. Unchecked = Low Priority (1×).
Mark All High Priority
Mark All Low Priority
N162 Math 8 High
L100 English 7 High
D110 Yearbook Low
86 course(s) marked High Priority · 3 Low Priority
SettingWhat it controlsDefault
Solver Time LimitMaximum seconds the solver runs. Longer = potentially better result, but slower.120s
Target Fill RateThe solver pushes to exceed this rate. Set above your current fill rate to drive improvement.75%
Auto-add ThresholdA new section is auto-added when SSS demand exceeds current capacity by more than this many students. Set to 0 to always scale; set high to disable.15
Period RearrangementAllows the optimizer to move unlocked sections to different periods to improve student fit. Teachers' full section groups move together.On ✓
Course Priority WeightsHigh-priority (10×) courses are scheduled before low-priority (1×) when there are conflicts. Overall fill rate % is unaffected — weights determine who wins ties.All high

Term-Orphan Prevention

A term orphan is a student whose final schedule fills some term slots but not all of them. The classic example is a student who ends up enrolled in Fall classes but has no Spring class, or — in a quarter school — a student with classes in Q1, Q2, Q4 but nothing in Q3. Term-orphan prevention is a soft solver preference that nudges the optimizer toward complete-term coverage.

How it works

The solver reviews each student whose requested courses reach more than one term slot. For each such student, it adds a penalty when their assigned schedule covers some slots but not all. The penalty is shaped to be:

What slots count

The slot vocabulary is determined automatically from your MST's Semester column. The optimizer detects whether you run a standard (F/S/Y), quarter (1/2/3/4), or trimester (T1/T2/T3) schedule and uses the matching slot set:

Term systemSlot setYear-long coverage
Standardfall, springA Y course covers both
Quarterfall_q1, fall_q2, spring_q3, spring_q4A Y course covers all four
TrimesterT1, T2, T3A Y course covers all three

Toggle

Term-orphan prevention is on by default. You can turn it off in Step 5 — Solver Settings. Look for the checkbox labeled "Prevent term-orphan student schedules".

💡If you see schedules where students end up with empty Spring periods despite Spring sections being available, leave this option on. If you have a population of part-time students whose requests legitimately don't span all terms, the algorithm already skips them — but if you're seeing false positives in the optimizer's behavior, you can disable it here.

Teacher term-orphan diagnostic

The same logic also runs for teachers — but as a diagnostic, not a constraint. The optimizer can't reassign sections between teachers (that's MST data), so a teacher with only Fall sections is a data-quality issue with the MST itself, not something the solver can fix. The diagnostic is computed post-solve and recorded with your session. A console log line summarizes the top offender:

Term-orphan diagnostic: 3 teacher(s) have partial term coverage.
Top offender: T#7 (filled=['fall'], missing=['spring'])

UI display of the full list is planned for a future release.

Term-Balance Auto-Clone (Heuristic)

The term-balance heuristic is a behind-the-scenes step that runs before the solver. It scans every (teacher, period) cell and asks: "does this cell run all year?" If a cell holds only Fall sections — and the highest-demand course in that cell crosses a threshold — the heuristic auto-clones that section into Spring so the cell covers both halves of the year. Same idea for quarter and trimester schools.

When does it fire?

For a clone to spawn, all of these must be true:

Toggle

The heuristic is on by default. You can turn it off in Step 5 — Solver Settings. Look for the checkbox labeled "Auto-clone for term balance (heuristic)" next to the term-orphan prevention checkbox.

💡Turn it off when you only want explicit Buddy Pairs to drive same-period term coverage. Buddy Pairs are visible and editable in Step 8 — the heuristic is invisible until you see clones on the results page. If you prefer a "what you declare is what you get" workflow, disable the heuristic.

Reviewing clones after a solve

Every clone the heuristic spawns appears in the Schedule Changes tab on the results page under Buddy-Class Auto-Clones. Each row shows the new section number, course, teacher, period, term, and demand. If a specific clone shouldn't have spawned, hide it via Step 2 (Locked Sections / pin-lock search) and re-run.

Staff Changes

Staff Changes is an optional wizard section shown with a ✓ checkmark in the sidebar (not a numbered step). Use it if teachers are departing or new teachers are joining before the schedule is finalized.

Click Staff Changes in the wizard sidebar to expand it. Select "Yes, there are changes" to reveal two lists — one for departing teachers (their sections will be released) and one for new teachers (assign them courses). If there are no changes, leave it at the default "No changes."

✅The most common scenario is no staff changes. This is the correct choice when running the optimizer for schedule analysis or incremental improvements — not when rebuilding the schedule from scratch.

Ready to Run

Once all wizard sections show a green ✅ in the sidebar, the footer bar shows ✓ All sections complete — ready to optimize! and the Save & Run Optimizer → button becomes active. Click it to save your settings and launch the solver.

💡Your wizard settings are saved immediately when you click Run. Even if the browser closes, you can return to the results page later — your constraints are preserved for re-runs.

Holding Tank

Holding Tank is the wizard's cleanup step for non-academic placeholder sections — Teacher Aides, Study Hall, Office Aide, X-prefix course codes, and similar courses that don't represent real instructional time. These sections inflate teacher loads and confuse the cluster grouping the optimizer uses, so they should be normalized before the solver runs.

How candidates are detected

The wizard scans your MST for courses that match either of two signals:

Each candidate is rated Very Likely (both signals match) or Likely (one signal matches) so you can sort by certainty.

Three actions per course

ActionWhat it doesWhen to use
Consolidate Removes all existing sections of this course, then injects one unassigned section per standard period with a very high seat capacity (999). Students requesting this course flow into whichever consolidated section has room. Frees teachers from non-academic loads while preserving every student request.
Drop Removes all sections of this course from the MST entirely. Student requests for the course remain on file and surface as unmet demand on the results page. The course is truly junk and you don't want to allocate any seats for it.
Leave (default) No change. Sections stay assigned to teachers exactly as in the original MST. The default — every candidate stays untouched until you opt in to Consolidate or Drop on the rows where it makes sense.
💡Why "Leave" is the default. The detector errs on the side of recall — it surfaces candidates the wizard thinks are placeholders, but you know your school better than the heuristic does. Leaving every row untouched by default means nothing is silently consolidated; you opt in row by row (or hit Consolidate all if the list is clean) once you've reviewed them.

How to use the step

  1. Open the wizard and scroll down to Step 6 — Holding Tank Courses (or click Holding Tank in the sidebar).
  2. Each detected course shows the confidence badge, course number and title, and the section/teacher/request counts.
  3. Pick an action per course by clicking the colored pill (Consolidate / Drop / Leave). Defaults are pre-set to Leave — change only the rows you actually want to act on.
  4. Use the Apply to all buttons at the top to mass-assign an action across every detected course.
  5. Continue with the rest of the wizard. Your decisions are saved when you click Save & Run Optimizer.
✅Student requests are always preserved. "Drop" only removes the sections, never the requests — if you want demand to disappear too, use the Resolve Missing Courses step's "Exclude" action instead.

Section Clusters

Section Clusters is the wizard's control over how the optimizer groups and moves sections during the period-rearrangement pass. A cluster is the set of sections a single teacher runs in one period — for example, all five Math classes Mr. Smith teaches in Period 2 form one cluster. Sections within a cluster always move together: if the optimizer decides to relocate any section in a cluster to a different period, the entire cluster moves with it.

How clusters are built

Live updates from Holding Tank decisions

The cluster list reacts immediately when you change a Holding Tank choice. If you mark a course as Drop or Consolidate, every section of that course virtually leaves its cluster — and if a cluster falls to a single remaining section, the row hides. Switching the same course back to Leave brings the cluster back into view if it goes above one section again.

This means you can configure Holding Tank first, scroll down to Section Clusters, and trust that what you see is what the optimizer will work with.

Filter and sort

Top 5 teachers, rest in an accordion

To keep the cluster step scannable on large schedules, only the top 5 teachers (ranked by total section count across all their clusters) appear in the main list. Everyone else is tucked into a collapsed accordion at the bottom labeled "Show N more teachers (M clusters)". Click it to expand the full list. The accordion is collapsed by default and auto-expands when a filter hit lands inside it — so search still works across every teacher.

Default state: Locked

Every auto-built cluster starts locked — pinned to its current period. The optimizer's period-rearrangement pass will not move any locked cluster. This is a conservative default that preserves your existing teacher arrangements unless you explicitly opt into movement.

💡If you want the optimizer to freely rearrange the schedule (the legacy behavior), click Unlock all at the top of the cluster step. The optimizer will then move clusters around to maximize student request fulfillment.

Operations

ActionWhat it does
Lock Pins a cluster to its current period. The optimizer will not move it during Pass 2.
Unlock Releases the pin. The optimizer is free to move the cluster to a different period if doing so improves student request fulfillment. Unlocking also reveals per-section chips with an X to drop individual sections.
Drop a single section (X chip) Only available when the cluster is unlocked. Click the small X next to a section chip to drop that one section from the schedule. The chip strikes through and the X becomes a restore arrow; click again to undo. This is the same effect as Step 2 → Drop, just scoped to one section inside a cluster.
Lock all / Unlock all Bulk operation across every real-teacher cluster. Singletons are skipped (they always move).
Reset to auto Discards your edits and reverts every cluster to its system-generated default state.

How to use the step

  1. Open the wizard and scroll to Step 7 — Section Clusters (or click Section Clusters in the sidebar).
  2. Each cluster shows the teacher name, the period, the section count, and a summary of the courses inside it. The lock icon on the left indicates current state.
  3. Use the filter input to search by teacher name, course, or period. Tick Mixed-semester only to see just the clusters that contain both Fall and Spring sections.
  4. Click the lock icon on any row to toggle that cluster between Locked and Unlocked, or use the bulk buttons at the top.
  5. Continue with the rest of the wizard. Cluster decisions are saved when you click Save & Run Optimizer.
✅Cluster definitions are persisted with your session. If you re-run the optimizer from the results page, your cluster locks come back exactly as you left them — no need to re-specify.

Manually adding a section (Step 2)

Step 2 (Section Locks) also exposes a small form for adding a section that does not exist in the MST yet — for example, a class you forgot to enter into Aeries before exporting. The form takes:

Manually-added sections behave like real sections from the MST after they're added: they participate in clusters, the term-balancing heuristic, and Pass-2 movement (unless you lock them).

Buddy Pairs

Buddy Pairs tell the optimizer which two courses should share a teacher. The classic cases are a yearlong sequence split across Fall/Spring (the same teacher continues with the same students into the next half) and a course paired with a back-to-back support class (kids walk from English into English Support next period). Step 8 of the wizard auto-detects candidates and lets you accept or reject each one.

Two pair types

TypePatternExample
Term Course A in Fall pairs with Course B in Spring (or vice versa). Same teacher continues with the same students. E101 (F) → E101 (S) continuation, or WHIST A (F) → WHIST B (S) rollover
Period Course A in Period N pairs with Course B in Period N+1 of the same day. Same teacher, students flow class-to-class. M101 (P3) → M101L (P4) Algebra + Algebra Support

How candidates are detected

The wizard scans your MST and SSS files for several signals:

Candidates matching two or more signals are rated Very Likely; one signal is Likely.

How to use the step

  1. Open the wizard and scroll to Step 8 — Buddy Pairs (or click Buddy Pairs in the sidebar).
  2. Switch between the Term Buddies and Period Buddies tabs to review each kind. The Period Buddies tab gets a stronger visual treatment in the tab nav so it doesn't get lost beside the default-open Term tab.
  3. For each candidate, click Accept if you want the optimizer to treat the pair as bound (soft preference: solver tries to give them the same teacher), or Reject to skip it.
  4. First-load default: every Very Likely candidate (term or period) is pre-set to Accept; everything else is pre-set to Reject. Tweak rows as needed. Once you save the wizard, your explicit decisions persist and the auto-default is not re-applied on later visits.
  5. Use the bulk buttons at the top to Accept all, Reject all, or Accept very-likely only in one click.
  6. Weak period-buddy pairs in an accordion. Period-buddy candidates whose only signal is same teacher, consecutive periods (no support keyword, no student rollover) are tucked into a collapsed accordion at the bottom of the Period Buddies tab — labeled "Show N weaker pairs". Click to expand if you want to review them; they default to Reject like any other Likely candidate.
  7. Continue with the rest of the wizard. Accepted pairs are saved when you click Save & Run Optimizer.
✅Same-teacher binding is a soft preference. The solver strongly prefers the bound teacher but will not fail if no teacher is available for both halves — the schedule still completes and the pair just shows up on different teachers.

Adding a manual buddy pair

Some pairs the auto-detector won't catch — for example, a pair you just decided to enforce, or a pair where the student rollover hasn't shown up yet because Spring requests aren't in the SSS. Use the Add buddy pair button on the right side of the bulk action row.

  1. Click Add buddy pair. An inline form appears.
  2. Pick the type — Term buddy for Fall→Spring continuation, Period buddy for back-to-back classes.
  3. Type Course A. The dropdown autocompletes from your MST course catalog. Course B defaults to Course A for term-continuation, but you can change it.
  4. Pick the semesters (term-buddy) or periods (period-buddy). Period B defaults to Period A + 1.
  5. Click Add & accept. Your new pair appears at the top of the matching tab with a Manual badge, already set to Accept.

Manual pairs are persisted with your session like any auto-detected pair. The Accept very-likely only bulk button leaves them alone — they're already accepted by default.

How the solver uses accepted pairs

For every accepted pair, the solver gives a small objective bonus to assignments where the same teacher runs both halves of the pair for the same student. The bonus is shaped so:

Team Buddies

Team Buddies bind a student's enrollments across N teamed courses to a single cohort. They live in the Buddy Pairs wizard step on a third tab labeled Team Buddies (imported). Unlike Term and Period buddies — which preference same teacher — team buddies are about same student cohort. The teachers can be the same person, a related team, or completely different people; what matters is that every student tagged to Team 100 stays in Team 100's section of every teamed course they take.

The two MST columns

ColumnAeries fieldWhat you put in it
TmCrsGrp MST.CG A short letter or label (e.g. "A") assigned to every section of every course that should be teamed. All English / Math / Science sections for a 9th-grade SLC, for example, get TmCrsGrp = "A".
Team# MST.TM An integer (e.g. 100, 101, 102) identifying a specific cohort within the group. All sections belonging to one cohort share the same Team#. Different cohorts of the same group get different Team#s.

How to tag sections

  1. Open the section's row in Aeries → SMS → Master Schedule.
  2. Set TmCrsGrp to a single letter shared by every section that should team together (e.g. all 9th-grade SLC sections get "A").
  3. Set Team# to a unique number per cohort. Every section of one cohort uses the same number. If the SLC has three cohorts of ~30 students each, assign 100, 101, 102 across the three parallel sets of sections.
  4. Leave both columns blank/0 on every section that shouldn't team — electives, PE, Lunch, etc. These sections allow free mixed enrollment.
  5. Re-export the MST with the updated query (the query block on the upload page already includes MST.SG MST.TM MST.CG) and re-upload to the optimizer.

Worked example

A 9th-grade SLC with three cohorts of English / Math / Science:

SectionCoursePeriodTmCrsGrpTeam#
1001E1011A100
1002M1012A100
1003S1013A100
1004E1012A101
1005M1013A101
1006S1011A101
1007E1013A102
1008M1011A102
1009S1012A102
1010PE015—0

A student requesting E101 + M101 + S101 will be routed into one of {100, 101, 102} for all three courses. The PE section is untagged so any student can land there regardless of cohort.

How the solver uses team buddies

For every accepted team group, the solver pays a strong soft penalty (default weight 50) per cohort-mismatch unit in a student's placement. The math:

Partial-request students

If a student requests only some of the team's courses (say English and Math but not Science), the binding still applies to the subset: the student is routed into one cohort for English and the same cohort for Math, but is free to land anywhere for Science (since they aren't requesting it).

The wizard UI

  1. Open Step 8 (Buddy Pairs) and click the Team Buddies (imported) tab on the right side of the tab nav.
  2. Each detected group renders as a card showing the TmCrsGrp letter, the list of teamed courses, the list of cohort numbers, and the number of students affected.
  3. Click "Show cohort breakdown" on any card to expand a grid of Team# × Course showing how many sections each cohort has of each course. An em-dash (—) in a cell means that cohort is missing a section for that course — the solver can't bind students to a missing cell.
  4. First-load default: every detected group is accepted. Untick the row to disable a group. Once saved, your decisions persist on later visits.

Silent skip rules

Some tagging patterns produce nothing the solver can act on:

💡Team buddies are orthogonal to same-teacher Buddy Pairs. You can have both: a Period Buddy says "give this student the same English teacher across P3 and P4," and a Team Buddy says "give this student the same cohort across English, Math, Science." They both fire and bind independently.

Results Page

After the optimizer finishes, you are taken to the Results page. This page has a top header bar with key stats and export buttons, followed by a row of tabs — each giving a different view of the optimized schedule.

Optimization Results FEASIBLE
MST.xlsx + SSS.xlsx · Solved in 72.7s
95.1%
Requests Satisfied
5,694/6,000
Student Requests Filled
761/1,007
Students Fully Scheduled
72.7s
Solve Time
Export results:
Overview
Sections
Students 191
Courses
Staffing Gaps 57
Schedule Changes 144
↑ Tab content shown below in each section

Header Stats

The four KPI numbers in the blue header update every time you re-run the optimizer. Requests Satisfied % is the primary metric. Student Requests Filled shows the raw count vs. total. Students Fully Scheduled counts students where every single request was placed. Solve Time shows how long the solver ran.

The badge next to the title shows the solver's final status: OPTIMAL means OR-Tools found the mathematically best solution; FEASIBLE means it found a valid solution that may improve with more time — try increasing the solver time limit in wizard settings and re-running.

Export Buttons

ButtonFormatUse for…
Excel WorkbookFormatted .xlsx (5 sheets)Visual review and sharing with administrators
Aeries SQL ExportDELETE + INSERT SQL scriptDirect import into Aeries SIS by a DBA or IT administrator
⚠️The SQL export uses the exact Aeries column schema. Have your DBA review the script before running it against the live database.

Overview Tab

The Overview tab is the landing tab on the Results page. It shows aggregate statistics about the optimized schedule in a card-and-chart layout — no row-level data.

Request Fill Rate
95.1%
5,694 of 6,000 requests filled
Fully Scheduled
72.1%
761 of 1,007 students
Empty Sections
61
Zero students assigned
At/Over Capacity
40
100%+ fill rate
Sections Per Period
P1
P2
P3
P4
P5
P6
Top Unfilled Courses
AP Chemistry28 unfilled
Drama 221 unfilled
Spanish 314 unfilled
Solver Info
Solver time12.4 s
Variables4,206
StatusOPTIMAL

What Each Card and Chart Shows

Card / ChartMeaning
Request Fill RatePercentage of all student course requests assigned to a section. This is the primary optimization target.
Fully ScheduledStudents where every single request was fulfilled, shown as both a percentage and a raw count.
Empty SectionsSections that exist in the schedule but had zero students assigned. Candidates for removal or consolidation.
At/Over CapacitySections where assigned enrollment meets or exceeds the section maximum. These may need a capacity bump or an added section.
Fill Rate DistributionDoughnut chart breaking down sections by enrollment band: 0%, 1–25%, 26–50%, 51–75%, 76–99%, 100%+.
Student Satisfaction BreakdownBar chart grouping students by how many of their requests were filled: 100% (fully scheduled), 75–99%, 50–74%, and <50%.
Enrollment by PeriodGrouped bar chart showing total Assigned enrollment vs. total Capacity for every period. Useful for spotting periods that are heavily under-utilized or over-booked.
Sections Below 50% Fill RateWarning table listing every section where enrollment is under 50% of its maximum. Columns: Section#, Period, Course#, Title, Teacher, Max, Assigned, Fill Rate. These sections are prime candidates for consolidation or period reassignment.
Staffing Comparison — Unique Teachers per PeriodTable showing how many distinct teachers are active each period in the Original vs. Optimized schedule, with a Delta column. A negative delta means the optimizer consolidated teachers out of that period; a positive delta means it spread teachers into it. The "All Periods" row shows the net change across all periods.
💡OPTIMAL means OR-Tools found the mathematically best solution within the time limit. FEASIBLE means it found a valid (but possibly improvable) solution — try increasing the solver time limit in wizard settings and re-running.

Sections Tab

The Sections tab shows the complete optimized master schedule — every section, its teacher, its period, its room, and how many students are enrolled. This is the closest view to what will be imported into Aeries.

Sec # Course Teacher Per Room Enrolled Cap Fill%
101 English 9 (N101) Smith J. 1 101 28 32 88%
102 Algebra 1 (M200) Garcia M. 1 205 31 32 97%
103 AP Chemistry (S410) Chen L. 2 312 18 24 75%
104 PE 9 (P100) Williams S. 3 GYM 40 50 80%
…84 total rows

Reading the Table

ColumnDescription
SECTION#Section number from the Aeries SMS extract. Auto-scaled sections added by the optimizer show a NEW badge.
PThe period this section is placed in.
COURSE#Aeries course number.
TITLECourse name. Auto-scaled sections show "(Auto-Scaled)" appended.
TEACHERTeacher name. "Unassigned" indicates a virtual section with no teacher yet — use Staffing Gaps to assign one.
ROOMRoom number from the original extract.
MAXSection capacity (maximum seats) from the original Aeries data.
ASSIGNEDStudents the optimizer placed in this section. Red text = zero or very low enrollment.
FILL RATEASSIGNED ÷ MAX shown as a color-coded progress bar and percentage.
CHANGENet change in enrollment vs. the original MST. Green = more students placed, red = fewer. A dash means no change.

Filtering and Searching

Use the filter box to search by course number, title, or teacher name. The All Periods dropdown narrows the table to a single period.

💡Look for NEW badged rows to see which sections the optimizer auto-added to meet demand. Sort by FILL RATE ascending to find the emptiest sections.

Students Tab

The Students tab shows only the students with unfilled requests — fully scheduled students are not listed here. The tab count badge (e.g., Students 160) tells you at a glance how many students have at least one unfilled course.

54
Period Conflict
Course has no section in a free period for this student
Add parallel section
63
Section Full
Section exists in a free period but has no remaining seats
Increase Max or add section
0
No Sections
Course has no sections in the active schedule
Missing Course wizard action
57
Solver Anomaly
Compatible section existed but student was not placed
Re-run optimizer
All (160) Period Conflict (54) Section Full (63)
Student# Requested Filled Missed Rate Unfilled Courses — Failure Reason
23905 9 6 3 66.7% P111 — PE 8 (Period Conflict) H120 — US History (Anomaly)
24341 7 4 3 57.1% N161 — Math 7 (Section Full)
…160 students with unfilled requests · click any row for full schedule & diagnostics

Failure Reason Cards

The four cards at the top summarize why requests went unfilled across all students:

ReasonMeaningRecommended Action
Period ConflictEvery section of the course is in a period already occupied by another of the student's placed courses.Add a parallel section in a different period via Staffing Gaps.
Section FullA section existed in a free period but all its seats were taken by other students.Increase the section Max (capacity bump) or add a second section.
No SectionsThe course appears in SSS requests but has no sections in the active schedule at all.Use the Missing Course wizard action to create sections.
Solver AnomalyA valid placement existed but the solver didn't make it — usually due to time limit pressure.Re-run with a longer solver timeout.

Filtering

Click the Period Conflict or Section Full filter pills to narrow the table to only students with that failure type. Use the Filter by Student# box to jump directly to a specific student.

Fix It Button

Rows where all missed requests are Section Full show a green ⚡ Fix it button. Clicking it pre-loads a capacity bump for that section into the wizard so you can immediately re-run without navigating to Staffing Gaps manually.

Student Detail Modal

Click any student row to open a full-schedule diagnostic modal showing every request, which section was assigned (or why it wasn't), and the failure category for each unfilled course.

⚠️Solver Anomaly failures are normal at high fill rates — the solver is racing against the time limit and occasionally leaves a valid placement on the table. Re-running with a longer timeout usually resolves most anomalies.

Courses Tab

The Courses tab aggregates results by course — showing how many sections exist, total seat capacity, how many students were assigned, and the overall fill rate. Use this tab to identify courses that are over- or under-served.

COURSE SUMMARY (90 COURSES)
COURSE# TITLE SECTIONS CAPACITY ASSIGNED FILL RATE
N162 Math 8 12 426 344 80.8%
L100 English 7 10 365 289 79.2%
P110 PE 7 5 220 206 93.6%

Column Reference

ColumnDescription
COURSE#Aeries course number.
TITLECourse name.
SECTIONSNumber of sections in the optimized schedule for this course.
CAPACITYCombined maximum seats across all sections of this course.
ASSIGNEDTotal students placed into this course by the optimizer.
FILL RATEASSIGNED ÷ CAPACITY as a percentage with color-coded bar.

What to Look For

Sort by FILL RATE ascending to find the most under-served courses — prime candidates for adding sections. High ASSIGNED numbers with low FILL RATE typically means demand exceeds capacity and period conflicts are blocking students.

💡Use the Courses tab together with the Staffing Gaps tab. Find the course with the worst fill rate here, then switch to Staffing Gaps to assign an underutilized teacher to a new section of that course.

Staffing Gaps Tab

The Staffing Gaps tab is an action tab — not just a report. It uses a two-panel Staffing Gap Matchmaker layout to connect available teachers with high-demand courses. The tab badge count shows the total number of stranded course-student combinations needing attention.

💡 Staffing Gap Matchmaker
Left: Teachers with open periods (their sections in that period had zero enrollment). Right: Courses with the most unplaced student requests. Click Assign → to pre-load a section into the wizard and re-run the optimizer.
Available Teachers (30)
Calle Jan P2 open P4 open
Was teaching 5 periods · Now 1 period
Currently: P1: X130 — Clerical Serv
Zero-enrollment: E520, E521, E541, E542…
Sender, Andrea P1 open P3 open
Was teaching 5 periods · Now 1 period
⚠ High-Demand Stranded Courses (25)
D110 Yearbook 13 period-conflict
13 students stranded
Best: P6 (7)
Free students by period: P6: 7 · P3: 3 · P5: 1
Assign to:
Abir I. P1 Andrea S. P3 Jan C. P6

Left Panel — Available Teachers

Shows every teacher who has at least one period where all their sections had zero enrollment (meaning students were not placed there). Each teacher card shows:

Right Panel — High-Demand Stranded Courses

Shows courses ranked by the number of students who could not be scheduled — sorted by unmet demand. Each course card shows:

After Assigning

Clicking a teacher-period pill immediately pre-loads the assignment into the wizard as a manual section. Re-run the optimizer to see the updated fill rate with the new section included.

⚠️Assigning a teacher here does not immediately update the results — it queues a constraint for the next optimizer run. Always re-run after making staffing assignments to see the impact.

Schedule Changes Tab

The Schedule Changes tab shows the impact of the optimizer's period rearrangement (Pass 2). It has four KPI cards at the top followed by two detail tables: Period Changes (sections that moved) and Auto-Added Sections (sections created to meet demand).

90.2%
Pass 1 Rate
Fixed-period baseline
96.1%
Final Rate
After period rearrangement
+5.9%
Improvement
From period rearrangement
60
Sections Moved
Period changed by optimizer
PERIOD CHANGES (60) Sections whose period was moved during Pass 2 rearrangement
SECTION# COURSE# COURSE TITLE TEACHER FROM PERIOD TO PERIOD
3058 A111 Color & Design 8 Nakajima, Snow Period 3 Period 1
5035 L110 English 8 Freestone Jessica Period 5 Period 1
…60 total period changes
AUTO-ADDED SECTIONS (34) New sections created because demand exceeded capacity by more than the threshold
SECTION# COURSE# PERIOD SSS DEMAND ORIGINAL CAPACITY OVERFLOW CAP ADDED
18051 H100 1 280 152 +128 +35
…34 total auto-added sections

KPI Cards

CardMeaning
Pass 1 RateFill rate achieved with original fixed periods, before any period rearrangement. This is the baseline the optimizer started from.
Final RateFill rate after period rearrangement (Pass 2) and re-solve (Pass 3). This is the number shown in the main header.
ImprovementThe gain from period rearrangement alone — Final Rate minus Pass 1 Rate. A positive value confirms rearrangement helped.
Sections MovedTotal number of sections whose period changed during Pass 2.

Period Changes Table

Lists every section the optimizer moved, showing Section#, Course, Teacher, the original period (FROM PERIOD), and the new period (TO PERIOD). Use this to verify no locked sections were moved unexpectedly. If you see an unwanted move, go back to the wizard and lock that section before re-running.

Auto-Added Sections Table

Lists virtual sections the optimizer created because SSS student demand exceeded the existing section capacity by more than the auto-add threshold. Columns:

ColumnMeaning
SSS DEMANDTotal student requests for this course from the SSS file.
ORIGINAL CAPACITYTotal seats that existed before auto-scaling.
OVERFLOWDemand minus original capacity — the gap the optimizer needed to fill.
CAP ADDEDSeats added by the new virtual section(s). Virtual sections show "Unassigned" as teacher — assign a real teacher via Staffing Gaps.
💡Review the Period Changes table before importing to Aeries. If you see unexpected MOVED sections, go back to the wizard and lock those sections before re-running.

Capacity Quick-Fix

The Capacity Quick-Fix feature appears in the Sections tab when a section has significantly low enrollment relative to its capacity — usually indicating that a period conflict is blocking students from accessing it. Quick-Fix lets you increase the section's enrollment cap or change its period without re-running the full optimizer.

⚠️Capacity Quick-Fix adjusts the schedule directly and is best used for small, targeted corrections. For systemic changes (many sections affected), it is better to adjust constraints in the wizard and re-run the optimizer.

When to Use It

Use Capacity Quick-Fix when you see a single section with very low enrollment (e.g., 5 students in a 30-seat class) and you know there are students who want it but are blocked by a period conflict. Bumping the cap rarely helps in this case — moving the section to a less-contested period is more effective.

Re-running the Optimizer

You can re-run the optimizer at any time without re-uploading your files. Your original MST/SMS and SSS data is preserved in the session, and your wizard constraints are saved automatically.

Current Constraints
✓ Standard periods: 1–6
✓ 3 sections locked
✓ Period rearrangement: On
✓ 1 manual section added
✓ Solver time limit: 60s
✓ No staff changes
Optimizer running… 14 / 60 seconds

Re-run Workflows

ScenarioRecommended Steps
You added a teacher in Staffing Gaps and want to see the impact Click Re-run Optimizer → in the toast notification, or navigate to the wizard and click Save & Run Optimizer.
Fill rate is low and you want to try a longer solver time Open the wizard → Solver Settings → increase the time limit → Save & Run Optimizer.
A section moved unexpectedly — you want to lock it and re-run Open the wizard → Section Locks → check the section to lock it → Save & Run Optimizer.
You want to start completely fresh Return to the home page and upload new files. This creates a new session with no preserved constraints.
💡Each re-run is a fresh solve — the optimizer doesn't "remember" the previous run's section assignments. If you've locked the right sections and set your manual staffing assignments, the results will be consistent across re-runs.

Tips & Troubleshooting

Common Issues

IssueLikely CauseFix
Fill rate is below 70% Too few sections for high-demand courses, or period conflicts are widespread Check Staffing Gaps tab → assign additional teachers → re-run. Also try enabling Period Rearrangement in Solver Settings.
Solver status is FEASIBLE, not OPTIMAL The time limit was reached before the solver found the best solution Increase solver time limit in wizard → Solver Settings → re-run.
A course appears in SSS but not in the Sections tab The course number in SSS was not mapped in the Missing Courses wizard step Return to wizard → Missing Courses → confirm or map the course number → re-run.
A section you locked still moved periods The lock was not saved before the last run, or Period Rearrangement moved a different section that you expected to stay Open wizard → Section Locks → verify the correct sections are checked → re-run.
File upload shows a parse error The CSV has trailing commas, extra blank rows, or BOM characters from Excel export Open the CSV in a text editor, remove trailing content, and re-save as UTF-8 CSV before uploading.

Best Practices

Start each scheduling cycle by uploading fresh exports from Aeries — never reuse an export from a prior year. Lock only the sections that are truly immovable (e.g., a teacher who can only teach a specific period due to a contract constraint). The more flexibility you give the optimizer, the higher the fill rate will be.

Run the optimizer first with default settings to get a baseline fill rate. Then iteratively improve: check the Staffing Gaps tab, add a section, re-run, and compare the new fill rate. Repeat until diminishing returns.

💡The optimizer is deterministic for a given set of constraints — the same inputs will produce the same output. This means you can confidently share results with colleagues knowing they will match if they re-run with the same settings.