OurClock · Optimization · Constraint Programming · Systems
Scheduling is easy until everyone has constraints.
OurClock started as a university software-design project and somehow turned into a multi-year scheduling system used to generate real academic timetables.
The hard part was never “put courses into time slots.”
The hard part was turning hundreds of small institutional rules (professor availability, room capacities, course conflicts, student cohorts, timing restrictions, preferences, and last-minute changes) into constraints a solver could actually reason about.
Google OR-Tools · CP-SAT · Integer Programming · FastAPI · MariaDB
- What it is
- Constraint-based university timetable scheduling system
- Timeline
- Sep 2023 – Apr 2026
- Role
- Co-founder · Optimization / Algorithm / Backend
- 300+ courses
- Deployed at Krea University
- 95% fewer scheduling conflicts in pilot testing
- Multi-term institutional use
See it run
It started because timetables were messy.
OurClock began as a Software Design project.
The first version was built in roughly three months.
At the time, the problem looked deceptively simple: take a list of courses, professors, rooms, and available slots, then generate a timetable without conflicts.
That version worked.
Then we tried using it on an actual university timetable. That was when the real problem appeared.
Real scheduling is full of rules that do not fit neatly into a spreadsheet cell.
- A professor may only be available at certain times.
- Two courses may share the same student cohort.
- A room may technically be free but too small.
- Some requirements are absolute.
- Others are preferences.
- And some constraints only become obvious when an administrator looks at the generated timetable and says, “No, we can’t actually do that.”
The project stopped being a timetable generator and became a constraint-modeling problem.
Before the solver can solve anything, the world has to become data.
Administrative inputs arrived as separate structured files and tables, each describing one slice of the institution:
- Courses
- Professors
- Professor availability
- Rooms
- Room capacities
- Student batches / cohorts
- Timings
- Course requirements
None of these can be scheduled in isolation. The system first has to validate them and normalize them into one consistent internal representation, so that a course, a professor or a room means the same thing in every table that mentions it.
- Excel / administrative inputs
- Validation + normalization
- Structured scheduling entities
- Constraint model
- Solver
- Generated timetable
- Validation
A timetable is an assignment problem.
For each course or teaching event, the system has to decide:
- when it happens
- where it happens
- which resources it consumes
X(course) = (time slot, room)
The solver searches for an assignment of every course such that all the required constraints stay satisfied at the same time.
CS201 Professor: P1 Batch: B2 Room capacity required: 60 Possible slots: Mon 10 Mon 11 Tue 10 Possible rooms: R101: 80 seats R203: 40 seats
| Room \ Slot | Mon 10 | Mon 11 | Tue 10 |
|---|---|---|---|
| R10180 seats | feasible | prof: Professor unavailable | batch: Batch already busy |
| R20340 seats | cap: Room too small | cap: Room too small | cap: Room too small |
- R203 is immediately invalid: 40 seats can’t hold a course that needs 60.
- Suppose Professor P1 is unavailable Monday at 11. Every Mon 11 placement is out.
- Suppose Batch B2 already has another course Tuesday at 10. Every Tue 10 placement is out.
The solver is not merely finding an empty box in a calendar.
It is searching for a globally feasible assignment, where every placement also limits every other course that shares a professor, a room or a cohort.
Not every rule is equally negotiable.
Hard constraints
These must never be violated.
- One room cannot host two classes simultaneously.
- One professor cannot teach two classes simultaneously.
- One student cohort cannot attend two required classes simultaneously.
- Room capacity must satisfy course requirements.
- Assignments must respect required professor availability.
- Valid room / course combinations must be respected.
Soft constraints
IllustrativeThese make one valid timetable better than another.
- Preferred teaching windows.
- Avoiding undesirable gaps.
- Balancing sessions across the week.
- Reducing awkward scheduling patterns.
- Satisfying institutional preferences where possible.
Illustrative examples of the kind of preference a timetable is judged on, not a list of what ran in production.
A valid timetable can still be a bad timetable.
Brute force gets ridiculous very quickly.
If there are n courses and each one has k possible room/time assignments, the naive search space is roughly kⁿ.
What it sounds like
100 × 20 = 2,000
100 courses, 20 possible assignments each.
What it actually is
20100 ≈ 1.3 × 10130
combinations, before a single constraint is checked.
Instead of enumerating everything, the solver uses constraints to eliminate impossible regions of the search space before fully exploring them.
That is what happened to CS201 above: six candidate placements, and propagation alone left one.
- Constraint propagation
- Every decision pushes its consequences onto the courses it touches.
- Domain reduction
- Placements that can no longer work are deleted from a course’s options.
- Search
- Make a choice, follow what it implies, keep going.
- Heuristic ordering
- Decide the most constrained courses first.
- CP-SAT
- OR-Tools’ solver, which combines propagation with SAT-style learning from conflicts.
The solver does the boring impossible part.
OurClock uses Google OR-Tools, with constraint and integer programming, to search for feasible timetable assignments. Conceptually, the loop looks like this:
- Choose an unresolved scheduling variable
- Try an assignment
- Propagate its consequences
- Conflict?
Early versions also involved search and heuristic ordering around highly constrained variables.
Assigning the hardest course first is often more useful than assigning the easiest one first.
Intuition: minimum remaining values
If one course only has two feasible placements while another has twenty, resolving the first one early exposes failure much sooner.
An intuition for why ordering matters, not a claim about the exact heuristic running in production.
The optimization model was only one part of the system.
- Admin inputs
- Data validation
- MariaDB
- Scheduling / constraint layer
- Google OR-Tools
- Generated timetable
- Validation
- Web interface
Supporting infrastructure
- FastAPI backend
- MariaDB
- Google Authentication
- Google OR-Tools
- Web frontend
- Structured administrative inputs
The solver could generate a timetable, but institutional deployment required authentication, persistent data, administrative workflows, validation, and a way for humans to actually inspect the output.
Then people actually used it.
OurClock moved beyond the original classroom project and was piloted at Krea University across multiple academic terms.
The system handled scheduling at the scale of hundreds of courses, rather than toy benchmark instances.
300+
courses handled at institutional scale
95%
reduction in scheduling conflicts during pilot testing
Multiple terms
used and piloted at Krea University
₹50K
paid deployment / project valuation at Krea
Discussions later extended to an institutional contract with IFMR College, Sri City.
Institutional contract discussions · proposed value ₹1.5 lakhThe algorithm wasn't actually the hardest part.
Once the solver existed, a different problem became obvious.
Universities change their minds.
- A professor becomes unavailable.
- A room disappears.
- A new course is added.
- A constraint that nobody mentioned suddenly becomes critical.
The solver does not care why a rule exists. It only knows the formal model it was given. It doesn’t know that a “preference” became non-negotiable this morning.
A technically valid timetable can therefore still be operationally wrong if the model is missing something humans implicitly understand.
A valid answer isn't always an understandable answer.
Once administrators started interacting with the system, another limitation became clear.
If the solver failed to produce the expected timetable, the useful question was not:
Did the solver fail?
Which assumptions made this schedule impossible?
That led to thinking about better diagnostics around:
- which constraints activated
- which rules became binding
- dependency chains between rules
- conflicts between assumptions
- minimal sets of constraints responsible for infeasibility
- targeted relaxations
Conflicting constraints:
- Professor unavailable Tue 9–12
- Batch B3 occupied Mon 10
- Required room capacity > 80
- Only compatible room occupied Wed 2
Possible adjustment:
→ Relax preferred Wednesday restriction
The next problem is letting humans describe constraints normally.
A solver understands variables and constraints.
Administrators think in sentences.
“Professor Mehta cannot teach before noon on Wednesdays.”
unavailable(Mehta, Wed, < 12:00)“Keep the first-year core courses spread across the week.”
spread(cohort = Y1-core, over = days)“This lab needs two consecutive slots.”
consecutive(lab, slots = 2)
The structured forms on the right are illustrative notation, not a real schema.
Today, adding a genuinely new constraint may require modifying the model or the structured input.
- Natural-language request
- Constraint extraction
- Structured representation
- Validation
- Solver constraint
- Schedule
- Evaluation
The language model should not replace the optimizer.
LLM
interprets the human request
Solver
searches for, and guarantees, mathematical feasibility
- Human
- Language model
- Structured constraint
- CP-SAT solver
- Validated timetable
Exploratory and ongoing. Not part of the original deployed version.
What I actually worked on
My work was concentrated around the scheduling logic: how the problem was represented, how constraints interacted, how the solver searched for feasible assignments, and how that optimization layer connected to the rest of the system.
- Co-founded the system
- Optimization / scheduling algorithm
- Constraint modeling
- Search and clustering-related technical work
- Solver architecture
- Backend integration
- Improving timetable generation
- Iterating through institutional deployment
OurClock was a team effort. I co-founded it, and my part centered on the optimization and scheduling logic.
What I learned
OurClock changed how I think about optimization.
The clean version of the problem is mathematical: define variables, define constraints, choose an objective, solve.
The real version starts one level earlier.
- Which constraints are actually real?
- Which ones are preferences?
- Which assumptions are missing?
- What should happen when reality changes tomorrow?
The solver can only be as good as the world we manage to describe to it.
That ended up being much more interesting to me than timetable generation itself.
The optimization, a level deeper
How the optimization works →
1. Variables
For every coursec:x_c= its time slot andr_c= its room.2. Domains
Each course starts with the slots its professor can teach and the rooms it may use:D(c) = { (t, r) : t ∈ Avail(prof(c)), r ∈ Rooms(c) }. Everything after this step shrinksD(c).3. Hard constraints
- Professor conflict:
x_i ≠ x_jfor coursesi, jtaught by the same professor. - Cohort conflict:
x_i ≠ x_jfor required courses of the same student cohort. - Room conflict:
(x_i, r_i) ≠ (x_j, r_j)for any two courses. - Capacity:
capacity(r_c) ≥ enrollment(c). - In integer-programming form, with
b_(c,t,r) ∈ {0,1}: each course placed once,Σ_(t,r) b_(c,t,r) = 1, and each room used once per slot,Σ_c b_(c,t,r) ≤ 1.
- Professor conflict:
4. Soft constraints / objectives
Preferences become penalties to minimise, e.g.minimise Σ_k w_k · violations_k. A feasible solution must satisfy every hard constraint; the objective only ranks feasible ones.5. Propagation
Fixingx_iimmediately removes values from the domains of every course that shares its professor, cohort or room. A domain that becomes empty is a conflict found before any further search.6. Search
Pick an unresolved variable (heavily constrained ones are good candidates), try a value, propagate.7. Backtracking / CP-SAT reasoning
On a conflict, undo the choice and try something else. CP-SAT also learns from conflicts, so the same dead end isn't explored twice.8. Validation
The generated timetable is checked against the constraints again, and by the people who will actually use it.
Stack
- Optimization
Google OR-Tools
CP-SAT
Constraint Programming
Integer Programming
Search / heuristics
- Backend
FastAPI
Python
MariaDB
- Product / Infrastructure
Google Authentication
Web application
Structured administrative inputs