Education
A university-scale LMS — from O(n×m) queries to O(1)
A university needed an LMS that could mirror its real structure — universities, colleges and courses — hold large lecture videos without losing an upload to a dropped connection, track a student's progress across several kinds of completion at once, and gate a course behind an approval step before it ever reached a student.
The challenge
Institutional structure, large video, and a progress bar that has to be true
The university's catalogue is not a flat list of courses — it is universities containing colleges containing courses, and every part of the platform (enrollment, permissions, reporting) has to respect that shape rather than fight it.
On top of that hierarchy sat two harder problems: lecture videos large enough that a single dropped connection could lose an hour of upload progress, and a per-student progress figure that had to reflect several different completion criteria — watched video, passed quiz, submitted assignment — without turning every dashboard load into a query that scanned every student against every piece of content. And before any of it reached a student, a course had to clear an approval workflow that only certain roles could operate.
What we built
A hierarchy in the schema, uploads that survive, progress that's precomputed
The university → college → course hierarchy is modelled directly as ForeignKey relationships, so permissions and queries follow the institution's own shape instead of an approximation of it. Video uploads go through django-tus and drf-chunked-upload, which track an upload session and let a large file resume from where a connection dropped rather than starting over.
Progress is not computed on read. Denormalized progress fields are updated through Django signals as a student completes something, with a Celery background task doing a batch recalculation whenever the underlying content changes — so a dashboard reads one precomputed number instead of joining across every completion record. A status-based workflow with admin approval gates, backed by custom RBAC permission classes, keeps who can publish, edit or approve a course tied to their actual role.
Multi-level hierarchy
Universities, colleges and courses as real ForeignKey relationships, matching how the institution is actually organised.
Resumable video upload
django-tus and drf-chunked-upload track an upload session, so a large lecture video survives a dropped connection.
Denormalized progress
Progress fields updated by Django signals as work is completed, with Celery batch recalculation when content changes.
Course approval workflow
A status-based workflow with admin approval gates before a course reaches a student.
Custom RBAC
Permission classes tied to institutional roles, not a single flat admin/student split.
Payments and coupons
Course payment integrated with a coupon system, gated behind JWT-authenticated sessions.
Under the hood
Django, Celery and S3 doing the work at university scale
- Django 5.0+
- Django REST Framework
- PostgreSQL
- SimpleJWT
- Celery 5.3+
- Redis
- django-tus
- drf-chunked-upload
- AWS S3
- Custom Permission Classes
- Django Signals
Celery and Redis carry the work that shouldn't block a request — batch progress recalculation, heavy background operations — while PostgreSQL and denormalized fields keep the common read path a single query.
Outcome
University-scale, resumable, and O(1) at read time
The university now runs an LMS that mirrors its own structure instead of forcing courses into a flat list, survives connection drops on large video uploads, and shows every student a progress figure that is precomputed rather than recalculated on every page load.
O(n×m) → O(1)
progress queries, via denormalization and signals
Resumable
chunked video uploads that survive a dropped connection
Background
Celery tasks handle batch recalculation and heavy operations
Need a platform that mirrors your real org chart?
Hierarchy, permissions and reporting that fight the org chart instead of matching it are how dashboards stop being trusted. We model the real shape first.