diff --git a/AKModel/admin.py b/AKModel/admin.py
index 8d60bc7e64647b1fe450a4832212bc898d11e8a2..8446259d31b0a3fad0a8b1c981d7151e4a578b2e 100644
--- a/AKModel/admin.py
+++ b/AKModel/admin.py
@@ -74,6 +74,8 @@ admin.site.register(Room)
 
 @admin.register(AKSlot)
 class AKSlotAdmin(admin.ModelAdmin):
+    readonly_fields = ['updated']
+
     def get_form(self, request, obj=None, change=False, **kwargs):
         # Use timezone of associated event
         if obj is not None and obj.event.timezone:
diff --git a/AKModel/models.py b/AKModel/models.py
index 997e85e22c3ef05676afbcda82e540e991c94b19..24ceb4d7e7a1771a34b293b549f41f57dd7d2562 100644
--- a/AKModel/models.py
+++ b/AKModel/models.py
@@ -1,8 +1,8 @@
-# Create your models here.
 import datetime
 import itertools
 
 from django.db import models
+from django.utils import timezone
 from django.utils.text import slugify
 from django.utils.translation import gettext_lazy as _
 from timezone_field import TimeZoneField
@@ -301,3 +301,12 @@ class AKSlot(models.Model):
         Retrieve end time of the AK slot
         """
         return self.start + datetime.timedelta(hours=float(self.duration))
+
+    @property
+    def seconds_since_last_update(self):
+        """
+        Return minutes since last update
+        :return: minutes since last update
+        :rtype: float
+        """
+        return (timezone.now() - self.updated).total_seconds()
diff --git a/AKPlan/templates/AKPlan/encode_events.html b/AKPlan/templates/AKPlan/encode_events.html
index 2cb97b193e59fa910a0f4e9ea187079fcf8a0d51..c38a4652b3ebfdd164362309e3dc645d617ad1a2 100644
--- a/AKPlan/templates/AKPlan/encode_events.html
+++ b/AKPlan/templates/AKPlan/encode_events.html
@@ -1,4 +1,5 @@
 {% load tz %}
+{% load tags_AKPlan %}
 
 [
     {% for slot in slots %}
@@ -8,8 +9,8 @@
                 'start': '{{ slot.start | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
                 'end': '{{ slot.end | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
                 'resourceId': '{{ slot.room.title }}',
-                'backgroundColor': '{{ slot.ak.category.color }}',
-                'borderColor': '{{ slot.ak.track.color }}',
+                'backgroundColor': '{{ slot|highlight_change_colors }}',
+                'borderColor': '{{ slot.ak.category.color }}',
                 'url': '{% url 'submit:ak_detail' event_slug=event.slug pk=slot.ak.pk %}'
             },
         {% endif %}
diff --git a/AKPlan/templatetags/__init__.py b/AKPlan/templatetags/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/AKPlan/templatetags/color_gradients.py b/AKPlan/templatetags/color_gradients.py
new file mode 100644
index 0000000000000000000000000000000000000000..1a9f96fd87eda8e405894eef648e048d81e87d32
--- /dev/null
+++ b/AKPlan/templatetags/color_gradients.py
@@ -0,0 +1,61 @@
+# gradients based on http://bsou.io/posts/color-gradients-with-python
+
+
+def hex_to_rgb(hex):
+    """
+    Convert hex color to RGB color code
+    :param hex: hex encoded color
+    :type hex: str
+    :return: rgb encoded version of given color
+    :rtype: list[int]
+    """
+    # Pass 16 to the integer function for change of base
+    return [int(hex[i:i+2], 16) for i in range(1,6,2)]
+
+
+def rgb_to_hex(rgb):
+    """
+    Convert rgb color (list) to hex encoding (str)
+    :param rgb: rgb encoded color
+    :type rgb: list[int]
+    :return: hex encoded version of given color
+    :rtype: str
+    """
+    # Components need to be integers for hex to make sense
+    rgb = [int(x) for x in rgb]
+    return "#"+"".join(["0{0:x}".format(v) if v < 16 else
+                        "{0:x}".format(v) for v in rgb])
+
+
+def linear_blend(start_hex, end_hex, position):
+    """
+    Create a linear blend between two colors and return color code on given position of the range from 0 to 1
+    :param start_hex: hex representation of start color
+    :type start_hex: str
+    :param end_hex: hex representation of end color
+    :type end_hex: str
+    :param position: position in range from 0 to 1
+    :type position: float
+    :return: hex encoded interpolated color
+    :rtype: str
+    """
+    s = hex_to_rgb(start_hex)
+    f = hex_to_rgb(end_hex)
+    blended = [int(s[j] + position * (f[j] - s[j])) for j in range(3)]
+    return rgb_to_hex(blended)
+
+
+def darken(start_hex, amount):
+    """
+    Darken the given color by the given amount (sensitivity will be cut in half)
+
+    :param start_hex: original color
+    :type start_hex: str
+    :param amount: how much to darken (1.0 -> 50% darker)
+    :type amount: float
+    :return: darker version of color
+    :rtype: str
+    """
+    start_rbg = hex_to_rgb(start_hex)
+    darker = [int(s * (1 - amount * .5)) for s in start_rbg]
+    return rgb_to_hex(darker)
diff --git a/AKPlan/templatetags/tags_AKPlan.py b/AKPlan/templatetags/tags_AKPlan.py
new file mode 100644
index 0000000000000000000000000000000000000000..5618fd57694fbfe75988bed3e9f3341f8a6c8818
--- /dev/null
+++ b/AKPlan/templatetags/tags_AKPlan.py
@@ -0,0 +1,20 @@
+from django import template
+
+from AKPlan.templatetags.color_gradients import darken
+from AKPlanning import settings
+
+register = template.Library()
+
+
+@register.filter
+def highlight_change_colors(akslot):
+    seconds_since_update = akslot.seconds_since_last_update
+
+    # Last change long ago? Use default color
+    if seconds_since_update > settings.PLAN_MAX_HIGHLIGHT_UPDATE_SECONDS:
+        return akslot.ak.category.color
+
+    # Recent change? Calculate gradient blend between red and
+    recentness = seconds_since_update / settings.PLAN_MAX_HIGHLIGHT_UPDATE_SECONDS
+    return darken("#b71540", recentness)
+    # return linear_blend("#b71540", "#000000", recentness)
diff --git a/AKPlanning/settings.py b/AKPlanning/settings.py
index fc67a5424a76e10519fbbe1a77bb1dfdd4c0027c..32eb423d6303d0afca26bba36142b8a565df9281 100644
--- a/AKPlanning/settings.py
+++ b/AKPlanning/settings.py
@@ -164,5 +164,7 @@ PLAN_WALL_HOURS_RETROSPECT = 3
 PLAN_WALL_HOURS_FUTURE = 18
 # Should the plan use a hierarchy of buildings and rooms?
 PLAN_SHOW_HIERARCHY = True
+# For which time (in seconds) should changes of akslots be highlighted in plan?
+PLAN_MAX_HIGHLIGHT_UPDATE_SECONDS = 2 * 60 * 60
 
 include(optional("settings/*.py"))