diff --git a/owl/home.py b/owl/home.py
index 7b7cdaa084acf4d68c3ef7ad6d3cb0bf689533bb..1654665fd87e81a3495e451224bab19c7fb92d1e 100644
--- a/owl/home.py
+++ b/owl/home.py
@@ -2,7 +2,7 @@
 
 from flask import g, request, url_for, render_template, redirect, session, flash
 from flask_wtf import FlaskForm
-from sqlalchemy import select, update, and_, or_
+from sqlalchemy import select, update, and_, or_, union, literal
 from sqlalchemy.orm import joinedload
 import sqlalchemy.sql.functions as func
 from typing import Dict, List, Tuple
@@ -21,34 +21,61 @@ def index():
     sess = db.get_session()
     semesters, enrolls, enrolls_by_sem = list_courses(True)
 
-    # For now, we calculate new post statictics only for teachers.
-    # It would be nice to extend it to students when we verify that
-    # the performance is reasonable. For students, we will need to
-    # limit target uids to g.uid and -1 (and probably mix these two
-    # together).
-    course_ids = set(e.course.cid for e in enrolls if e.is_teacher)
+    course_ids_teacher = set(e.course.cid for e in enrolls if e.is_teacher)
+    course_ids_student = set(e.course.cid for e in enrolls if not e.is_teacher)
+    course_ids = course_ids_teacher | course_ids_student
     if course_ids:
-        mtime_subq = (
-            select(db.Topic.cid, db.Post.tid, db.Post.target_uid, func.max(db.Post.created).label('last_created'), func.max(db.Post.modified).label('last_modified'))
-            .select_from(db.Post)
-            .join(db.Topic)
-            .filter(db.Topic.cid.in_(course_ids))
-            .filter(db.Post.target_uid >= 0)
-            .filter(db.Post.author_uid >= 0)
-            .group_by(db.Topic.cid, db.Post.tid, db.Post.target_uid)
-            .subquery()
-        )
-
-        seen_subq = (
-            select(db.Seen.tid, db.Seen.target_uid, func.max(db.Seen.seen).label('last_seen'))
-            .select_from(db.Seen)
-            .join(db.Topic, db.Topic.tid == db.Seen.tid)
-            .join(db.Enroll, and_(db.Enroll.cid == db.Topic.cid, db.Enroll.uid == db.Seen.observer_uid))
-            .filter(db.Enroll.cid.in_(course_ids))
-            .filter(db.Enroll.is_teacher == True)
-            .group_by(db.Seen.tid, db.Seen.target_uid)
-            .subquery()
-        )
+        mtime_subqs = []
+        seen_subqs = []
+
+        if course_ids_teacher:
+            # Consider non-global posts in all threads of the course
+            mtime_subqs.append(
+                select(db.Topic.cid, db.Post.tid, db.Post.target_uid, func.max(db.Post.created).label('last_created'), func.max(db.Post.modified).label('last_modified'))
+                .select_from(db.Post)
+                .join(db.Topic)
+                .filter(db.Topic.cid.in_(course_ids_teacher))
+                .filter(db.Post.author_uid >= 0)
+                .filter(db.Post.target_uid >= 0)
+                .group_by(db.Topic.cid, db.Post.tid, db.Post.target_uid)
+            )
+
+            # Consider acknowledges by all teachers of the course
+            seen_subqs.append(
+                select(db.Seen.tid, db.Seen.target_uid, func.max(db.Seen.seen).label('last_seen'))
+                .select_from(db.Seen)
+                .join(db.Topic, db.Topic.tid == db.Seen.tid)
+                .join(db.Enroll, and_(db.Enroll.cid == db.Topic.cid, db.Enroll.uid == db.Seen.observer_uid))
+                .filter(db.Enroll.cid.in_(course_ids_teacher))
+                .filter(db.Enroll.is_teacher == True)
+                .group_by(db.Seen.tid, db.Seen.target_uid)
+            )
+
+        if course_ids_student:
+            # Consider only global posts and posts in my threads, all in public topics only
+            mtime_subqs.append(
+                select(db.Topic.cid, db.Post.tid, literal(g.uid).label('target_uid'), func.max(db.Post.created).label('last_created'), func.max(db.Post.modified).label('last_modified'))
+                .select_from(db.Post)
+                .join(db.Topic)
+                .filter(db.Topic.cid.in_(course_ids_student))
+                .filter(db.Topic.public == True)
+                .filter(db.Post.author_uid >= 0)
+                .filter(db.Post.target_uid.in_((g.uid, -1)))
+                .group_by(db.Topic.cid, db.Post.tid)
+            )
+
+            # Consider only my acknowledges
+            seen_subqs.append(
+                select(db.Seen.tid, literal(g.uid).label('target_uid'), func.max(db.Seen.seen).label('last_seen'))
+                .select_from(db.Seen)
+                .join(db.Topic, db.Topic.tid == db.Seen.tid)
+                .filter(db.Seen.observer_uid == g.uid)
+                .filter(db.Topic.cid.in_(course_ids_student))
+                .group_by(db.Seen.tid)
+            )
+
+        mtime_subq = union(*mtime_subqs).subquery()
+        seen_subq = union(*seen_subqs).subquery()
 
         new_post_counts = sess.execute(
             select(mtime_subq.c.cid, func.count())