diff --git a/src/core/triggerset.py b/src/core/triggerset.py
index 5ef76f0..b5dca51 100644
--- a/src/core/triggerset.py
+++ b/src/core/triggerset.py
@@ -150,6 +150,8 @@ class _Trigger:
         self._usage_cb = usage_cb
         self._default_one_time = default_one_time
         self._remove_bad_handlers = remove_bad_handlers
+        self._profile_next_run = False
+        self._profile_params = None
 
     def add(self, handler):
         if self._locked:
@@ -171,7 +173,29 @@ class _Trigger:
         if self._usage_cb and len(self._handlers) == len(self._pending_del):
                 self._usage_cb(self._name, 0)
 
+    def profile_next_run(self, sort_by='time', num_entries=20):
+        self._profile_next_run = True
+        self._profile_params = {'sort_by': sort_by, 'num_entries': num_entries}
+
     def activate(self, data):
+        if not self._profile_next_run:
+            self._activate(data)
+            return
+        import cProfile, pstats, io
+        params = self._profile_params
+        pr = cProfile.Profile()
+        pr.enable()
+        self._activate(data)
+        pr.disable()
+        s = io.StringIO()
+        ps = pstats.Stats(pr, stream=s).sort_stats(params['sort_by'])
+        ps.print_stats(params['num_entries'])
+        print('Profile for last activation of {} trigger:'.format(self._name))
+        print(s.getvalue())
+        self._profile_next_run = False
+
+
+    def _activate(self, data):
         if self._blocked:
             # don't raise trigger multiple times for identical
             # data
@@ -350,6 +374,22 @@ class TriggerSet:
         """
         self._triggers[name].release()
 
+    def profile_trigger(self, name, sort_by='time', num_entries=20):
+        """Supported API. Profile the next firing of the given trigger.
+
+        triggerset.profile_trigger(name) => None
+
+        The resulting profile information will be printed to the ChimeraX log.
+        The optional sort_by argument may be any of the arguments allowed by
+        Python's `pstats.sort_stats()` method. Typically, the most useful of
+        these are:
+
+        'calls':        call count
+        'cumulative':   cumulative time
+        'time':         internal time 
+        """
+        self._triggers[name].profile_next_run(sort_by=sort_by, num_entries=num_entries)
+
     def has_trigger(self, name):
         """Supported API. Check if trigger exists."""
         return name in self._triggers
