Every semester, somebody at a university spends two to three weeks moving coloured blocks around a spreadsheet while 4,000 students wait for a schedule. The combinatorics are brutal: a mid-sized institution with 400 courses, 60 rooms and 25 timeslots has on the order of 10^40 nominal assignments, of which maybe a few thousand satisfy hard constraints like “Professor Chen cannot teach two rooms at once.”

Commercial timetabling suites charge per-student licensing for solving this. Three open-source projects solve it for free, and they are not interchangeable: one is a full institutional platform, one is a Java constraint engine you embed in your own service, and one is a desktop generator that finishes in ninety seconds. Picking the wrong one costs you a semester. This guide compares all three on real deployment mechanics, not marketing pages.

TL;DR

  • You are a registrar or IT team at a school/university and want a web UI, student course requests, exam scheduling and multi-campus support → UniTime. It is the only one of the three that is a complete timetabling system.
  • You are a developer and timetabling is one feature inside a larger application (rostering, exams, bus routing, factory shifts) → Timefold Solver. You model constraints in Java or Kotlin and get a solver, not a UI.
  • You need a printable timetable by Friday, you have no DBA, and your data lives in spreadsheets → FET. Single binary, no database, no server, XML in and XML out.

If you deploy UniTime expecting a solver library you will fight it for weeks. If you deploy FET expecting a multi-user web platform you will hit a wall on day two. The failure mode is always a mismatch of category, not of quality.

Side-by-side comparison

DimensionUniTimeTimefold SolverFET
GitHub stars3581,867Not on GitHub (released on lalescu.ro / SourceForge)
Primary languageJavaJava / KotlinC++ (Qt)
LicenseApache-2.0 (Apereo Foundation)Apache-2.0GPL-2.0+
Deployment modelTomcat + MySQL, official Docker composeLibrary dependency (Maven/Gradle), Quarkus/Spring Boot samplesDesktop app + fet-cl headless CLI
Database requiredMySQLNone (your model lives in your app)None (XML data file)
Web UIYes, full administrative UINo (bring your own)Desktop GUI, HTML export
Multi-userYes, roles, departments, student course requestsNo (embedded)Single operator
Hard/soft constraint modelFixed, domain-specificFully programmable in codeConfigurable weights in the GUI/XML
Last commit (checked)2026-11-122026-11-11Active 7.x series
Realistic time to first timetable2-6 weeks1-3 days for a developer1-2 days

Decision matrix

Your situationPickWhy
5,000 students, 12 departments, exam weeksUniTimeCourse requests, departmental permissions and exam scheduling are built in
You are shipping a rostering feature in a SaaS productTimefoldApache-2.0, embeddable, constraint streams in plain Java
A single faculty needs a schedule once a semesterFETNo database, no server, printable output
You need vehicle routing and timetabling in one codebaseTimefoldSame engine solves both (VRP and planning)
You have no Linux admin and only Windows desktopsFETInstalls like a normal desktop program
You want to expose a public API for timetablingUniTime or TimefoldUniTime has a web layer; Timefold gives you the engine to wrap

UniTime — the full institutional platform

UniTime is the one project here that behaves like enterprise software because it is enterprise software: it has been deployed at universities across North America and Europe for close to two decades, and it is governed by the Apereo Foundation, the same organization behind Sakai.

What you get out of the box:

  • Course timetabling across multiple campuses and terms, with room and instructor constraints.
  • Student course requests — students rank the sections they want, and UniTime optimises section assignment against those preferences.
  • Examination timetabling with conflict matrices, back-to-back rules and room capacity handling.
  • Event management for ad-hoc bookings that must not collide with classes.
  • Role-based access so a department scheduler can only touch their own courses.

The deployment is a two-container stack: MySQL and Tomcat. The repository ships a working compose file under Documentation/Docker/, which is the sane starting point:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
services:
    unitime-db:
        container_name: unitime-db
        command: --default-authentication-plugin=mysql_native_password
        environment:
            - MYSQL_RANDOM_ROOT_PASSWORD=yes
            - MYSQL_USER=timetable
            - MYSQL_PASSWORD=unitime
            - MYSQL_DATABASE=timetable
        volumes:
            - "unitime-db:/var/lib/mysql"

    unitime-web:
        container_name: unitime-web
        depends_on:
            - unitime-db
        environment:
            - JAVA_OPTS=-Dconnection.url=jdbc:mysql://unitime-db:3306/timetable
        ports:
            - "8080:8080"

Two things bite people here. First, the images are built locally from mysql.Dockerfile and tomcat.Dockerfile; there is no official prebuilt image, so a first docker compose up --build takes a while and needs network access for the Maven and package downloads. Second, MYSQL_RANDOM_ROOT_PASSWORD=yes means you must read the generated root password from the container logs (docker logs unitime-db | grep -i "GENERATED ROOT PASSWORD") before you can run any administrative SQL.

UniTime’s honest weakness: the constraint model is opinionated. If your institution has a rule nobody else has — say, “no lab session may start in the same building as a lecture that ends five minutes earlier” — you may end up modifying Java rather than editing a config file. Budget for a developer who can read Hibernate mappings if your requirements are unusual.

Timefold Solver — the embeddable constraint engine

Timefold is the actively maintained successor to OptaPlanner: same author lineage, cleanly relicensed, and now the fastest-moving project of the three with 1,867 stars and commits landing daily. It is not a timetabling application. It is a constraint solver with a planning model, and timetabling is one of the problem shapes it handles well.

The programming model is annotation-driven. You declare which field is the planning variable, supply a value range, and write constraints as streams:

1
2
3
4
5
6
7
8
9
@PlanningEntity
public class Lecture {

    @PlanningVariable(valueRangeProviderRefs = "timeslotRange")
    private Timeslot timeslot;

    @PlanningVariable(valueRangeProviderRefs = "roomRange")
    private Room room;
}

Constraints are code, which is the whole point:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public Constraint[] defineConstraints(ConstraintFactory factory) {
    return new Constraint[] {
        // Hard: a room hosts at most one lecture per timeslot
        factory.forEachUniquePair(Lecture.class,
                Joiners.equal(Lecture::getRoom),
                Joiners.equal(Lecture::getTimeslot))
            .penalize(HardSoftScore.ONE_HARD)
            .asConstraint("Room conflict"),

        // Hard: an instructor cannot be in two rooms at once
        factory.forEachUniquePair(Lecture.class,
                Joiners.equal(Lecture::getInstructor),
                Joiners.equal(Lecture::getTimeslot))
            .penalize(HardSoftScore.ONE_HARD)
            .asConstraint("Instructor conflict"),

        // Soft: avoid 8am starts
        factory.forEach(Lecture.class)
            .filter(l -> l.getTimeslot().getStartHour() < 9)
            .penalize(HardSoftScore.ONE_SOFT)
            .asConstraint("Early start")
    };
}

Add the solver as a dependency (timefold-solver-core on Maven Central) and run it:

1
2
3
4
5
6
7
8
SolverFactory<CourseSchedule> factory = SolverFactory.create(
    new SolverConfig()
        .withSolutionClass(CourseSchedule.class)
        .withEntityClasses(Lecture.class)
        .withConstraintProviderClass(TimetableConstraintProvider.class)
        .withTerminationSpentLimit(Duration.ofMinutes(2)));

CourseSchedule solved = factory.buildSolver().solve(problem);

This is where Timefold earns its stars: two minutes of solver time on a 400-lecture problem typically produces a schedule with zero hard-constraint violations and a soft score you can tune by reweighting constraints in code. The catch is that you own everything around it — data model, persistence, authentication, UI, and the explanation of why a schedule is bad (which registrars always ask).

Do not underestimate that last part. UniTime ships screens that explain conflicts; with Timefold you build them.

FET — the offline generator that still wins on simplicity

FET (Free Timetabling Software) is the pragmatic outlier: a Qt desktop application by Liviu Lalescu, available in Debian and Ubuntu repositories, with a headless command-line companion called fet-cl. It has no database, no server, and no login. Your entire problem is one XML file.

Installing it on a Debian/Ubuntu workstation or server is a one-liner:

1
2
sudo apt update && sudo apt install -y fet
fet-cl --version

The headless workflow is what makes FET usable in automation:

1
2
# Generate a timetable from an existing data file, 20 seconds budget
fet-cl --inputfile=school.fet --outputdir=out --timelimitseconds=20

And the generated .fet file is plain XML, so you can generate it from your student information system with a script instead of clicking through the GUI:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<Activities_List>
    <Activity>
        <Teacher>Chen</Teacher>
        <Subject>Algorithms</Subject>
        <Students>CS-Year2</Students>
        <Duration>2</Duration>
        <Total_Duration>2</Total_Duration>
        <Id>101</Id>
        <Activity_Group_Id>0</Activity_Group_Id>
    </Activity>
</Activities_List>

FET’s constraint system covers the practical 90%: teacher and student set conflicts, room preferences, min/max days between activities, and activity tags for “this lab needs a projector room”. Its solver is single-threaded and old-fashioned compared to Timefold, but for a single faculty with 60 activities it finishes in seconds.

Where FET breaks: anything multi-user. No concurrent editors, no permissions, no audit trail, no API. If two people need to touch the data, you are back to emailing XML files. It also does not scale gracefully to 5,000-activity university problems — expect long runs and manual constraint relaxation.

Deployment pitfalls worth knowing before you start

  1. UniTime’s Docker build is not a pull-and-run. Plan for a 10-20 minute first build and pin the MySQL image tag; an unexpected MySQL 9 upgrade will break the native password authentication flag used in the compose file.
  2. Timefold scores are only comparable within one constraint set. Team A’s -1200 soft score is meaningless next to Team B’s -40. Publish the constraint weights alongside the score or you will argue about nothing.
  3. FET’s XML is strict about IDs. Duplicate Id values silently collapse activities during import; validate uniqueness before generating the file.
  4. Time limits are not quality guarantees. Timefold’s withTerminationSpentLimit and FET’s --timelimitseconds both return the best solution found so far. Always check the hard score is zero before publishing a timetable, never assume “it ran without errors” means “it is feasible”.
  5. Semester rollover is the real test. Whichever tool you pick, run a full dry run on last semester’s real data before committing to it. All three will happily produce a beautiful, invalid timetable.

For related scheduling reading, see our constraint programming solver comparison if you plan to hand-roll the model, and the school management system guide for the surrounding student data. If your problem is closer to queueing than timetabling, the discrete event simulation frameworks review covers that ground.

FAQ

Is UniTime really free for a whole university?

Yes. UniTime is Apache-2.0 licensed under the Apereo Foundation, with no per-student fee. Your real costs are infrastructure (a MySQL instance and a Tomcat container) and the staff time to configure rooms, curricula and constraints. Institutions typically spend two to six weeks on initial configuration before the first real semester.

Can FET handle a university-sized problem?

Usually not comfortably. FET is designed for school-level problems — a few hundred activities. Beyond roughly 1,000 activities, generation times grow sharply and you end up manually relaxing constraints. For university scale, UniTime or a Timefold-based service is the better fit.

Do I need to know Java to use Timefold?

Yes, for anything beyond the sample projects. Timefold’s model is Java/Kotlin classes with annotations, and constraints are code. If your team is Python-only, either wrap a solver service in Java or look at constraint programming tools with Python bindings instead.

Which one produces the most optimised timetable?

Timefold, by a wide margin, because you can weight and tune every soft constraint and give the solver real CPU time. UniTime’s optimiser is good but its objective is fixed by the platform’s design. FET is a fast feasibility generator, not an optimiser.

Can I run timetabling in a container with no GUI at all?

Yes for all three, with different mechanisms: UniTime is a web application by design, Timefold runs inside your own service (often a Quarkus or Spring Boot container), and FET exposes fet-cl for headless generation from an XML file.

How do I move data between them?

Realistically you do not. UniTime stores everything in MySQL, Timefold keeps the model in your application, and FET uses XML. Practical migration means exporting to CSV and rebuilding the model — plan a parallel run for one semester rather than a cutover.


💰 想测试你的市场判断力?我用 Polymarket 做预测市场交易——这是全球最大的预测市场平台,从大选结果到技术监管时间线,什么都可以押注。和赌博不同,这是真正的信息市场:你懂的信息越多,胜率越高。我靠预测技术相关事件的走向已经赚了不少。用我的邀请链接注册:Polymarket.com