Index: backend/auth_form/signals.py
===================================================================
--- backend/auth_form/signals.py	(revision 9c6c398f8a7679628452d43705e741cae8e5bbf2)
+++ backend/auth_form/signals.py	(revision 770bcb8e6383b7118062c2f9fa056e861be140ad)
@@ -1,5 +1,7 @@
+from django.core.cache import cache
 from django.db.models.signals import post_save
 from django.dispatch import receiver
 from .models import User, Student
+from subjects.utils import get_recommendations_cache_key
 
 @receiver(post_save, sender=User)
@@ -11,3 +13,9 @@
 def save_student_profile(sender, instance, **kwargs):
     instance.student.save()
-    
+
+@receiver(post_save, sender=Student)
+def invalidate_recommendations_cache(sender, instance, **kwargs):
+    for season in [0,1,2]:
+        cache_key = get_recommendations_cache_key(instance, season)
+        if cache_key:
+            cache.delete(cache_key)
Index: backend/backend/settings.py
===================================================================
--- backend/backend/settings.py	(revision 9c6c398f8a7679628452d43705e741cae8e5bbf2)
+++ backend/backend/settings.py	(revision 770bcb8e6383b7118062c2f9fa056e861be140ad)
@@ -110,4 +110,11 @@
 }
 
+CACHES = {
+    'default': {
+        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
+        'LOCATION': 'recommendations_cache',
+    }
+}
+
 # Password validation
 # https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators
Index: backend/subjects/utils.py
===================================================================
--- backend/subjects/utils.py	(revision 9c6c398f8a7679628452d43705e741cae8e5bbf2)
+++ backend/subjects/utils.py	(revision 770bcb8e6383b7118062c2f9fa056e861be140ad)
@@ -23,4 +23,9 @@
     TAG_GRAPH = json.load(f)
 
+def get_recommendations_cache_key(student, season):
+    passed_subjects_hash = hash(tuple(sorted(student.passed_subjects.values_list('id', flat=True))))
+    cache_key = (f"student_{student.id}_season_{season}_effort_{student.study_effort}"
+                 f"_year_{student.current_year}_passed_{passed_subjects_hash}")
+    return cache_key
 
 def get_eligible_subjects(student, season = 2):
Index: backend/subjects/views.py
===================================================================
--- backend/subjects/views.py	(revision 9c6c398f8a7679628452d43705e741cae8e5bbf2)
+++ backend/subjects/views.py	(revision 770bcb8e6383b7118062c2f9fa056e861be140ad)
@@ -1,6 +1,5 @@
 import json
-from django.http import HttpResponse, JsonResponse
-from django.shortcuts import render
-from django.db import connection
+from django.http import HttpResponse
+from django.core.cache import cache
 from rest_framework.decorators import api_view
 from rest_framework.response import Response
@@ -9,9 +8,7 @@
 from rest_framework.permissions import IsAuthenticated
 from django.db.models import Case, When
-from auth_form.serializers import StudentFormSerializer
-from subjects.utils import get_eligible_subjects, get_recommendations, map_to_subjects_vector, score_for_preferences, get_student_vector
+from subjects.utils import get_eligible_subjects, get_recommendations, get_recommendations_cache_key, map_to_subjects_vector, score_for_preferences, get_student_vector
 from .serializers import SubjectSerializer
-from .models import Subject_Info, Subject
-from datetime import datetime
+from .models import Subject
 
 def index(request):
@@ -36,4 +33,9 @@
     if not student:
         return Response({"message": "Could not find student"}, status=status.HTTP_400_BAD_REQUEST)
+    cache_key = get_recommendations_cache_key(student, season)
+    if cache_key:
+        cached_data = cache.get(cache_key)
+        if cached_data:
+            return Response({"data": json.loads(cached_data)}, status=status.HTTP_200_OK)
     try:
         subjects = get_eligible_subjects(student, season=season)
@@ -48,4 +50,6 @@
 
         serializer = SubjectSerializer(recommended_subject_objects, many=True)
+        if cache_key:
+            cache.set(cache_key, json.dumps(serializer.data), timeout=60 * 60 * 24 * 14) # 14 days  
         return Response({"data": serializer.data}, status=status.HTTP_200_OK)
     
@@ -60,5 +64,4 @@
         try:
             student = request.user.student
-            # .values_list('id', flat=True) is very efficient
             favorite_ids = list(student.favorite_subjects.all().values_list('id', flat=True))
             liked_ids = list(student.liked_subjects.all().values_list('id', flat=True))
