Index: trac/ticket/api.py
===================================================================
--- trac/ticket/api.py	(revision 6843)
+++ trac/ticket/api.py	(working copy)
@@ -16,6 +16,10 @@
 
 import re
 from datetime import datetime
+try:
+    import threading
+except ImportError:
+    import dummy_threading as threading
 
 from genshi.builder import tag
 
@@ -152,6 +156,7 @@
     def __init__(self):
         self.log.debug('action controllers for ticket workflow: %r' % 
                 [c.__class__.__name__ for c in self.action_controllers])
+        self._fields_lock = threading.RLock()
 
     # Public API
 
@@ -180,6 +185,26 @@
 
     def get_ticket_fields(self):
         """Returns the list of fields available for tickets."""
+        # This is now cached - as it makes quite a number of things faster,
+        # e.g. #6436
+        if self._fields is None:
+            self._fields_lock.acquire()
+            try:
+                self._fields = self._get_ticket_fields()
+            finally:
+                self._fields_lock.release()
+        return [f.copy() for f in self._fields]
+
+    def reset_ticket_fields(self):
+        self._fields_lock.acquire()
+        try:
+            self._fields = None
+            self.config.touch() # brute force approach for now
+        finally:
+            self._fields_lock.release()
+
+    _fields = None
+    def _get_ticket_fields(self):
         from trac.ticket import model
 
         db = self.env.get_db_cnx()
@@ -251,6 +276,16 @@
         return fields
 
     def get_custom_fields(self):
+        if self._custom_fields is None:
+            self._fields_lock.acquire()
+            try:
+                self._custom_fields = self._get_custom_fields()
+            finally:
+                self._fields_lock.release()
+        return [f.copy() for f in self._custom_fields]
+
+    _custom_fields = None
+    def _get_custom_fields(self):
         fields = []
         config = self.config['ticket-custom']
         for name in [option for option, value in config.options()
Index: trac/ticket/model.py
===================================================================
--- trac/ticket/model.py	(revision 6843)
+++ trac/ticket/model.py	(working copy)
@@ -393,6 +393,7 @@
             db.commit()
         self.value = self._old_value = None
         self.name = self._old_name = None
+        TicketSystem(self.env).reset_ticket_fields()
 
     def insert(self, db=None):
         assert not self.exists, 'Cannot insert existing %s' % self.type
@@ -418,6 +419,7 @@
             db.commit()
         self._old_name = self.name
         self._old_value = self.value
+        TicketSystem(self.env).reset_ticket_fields()
 
     def update(self, db=None):
         assert self.exists, 'Cannot update non-existent %s' % self.type
@@ -444,6 +446,7 @@
             db.commit()
         self._old_name = self.name
         self._old_value = self.value
+        TicketSystem(self.env).reset_ticket_fields()
 
     def select(cls, env, db=None):
         if not db:
@@ -530,6 +533,7 @@
 
         if handle_ta:
             db.commit()
+        TicketSystem(self.env).reset_ticket_fields()
 
     def insert(self, db=None):
         assert not self.exists, 'Cannot insert existing component'
@@ -549,6 +553,7 @@
 
         if handle_ta:
             db.commit()
+        TicketSystem(self.env).reset_ticket_fields()
 
     def update(self, db=None):
         assert self.exists, 'Cannot update non-existent component'
@@ -574,6 +579,7 @@
 
         if handle_ta:
             db.commit()
+        TicketSystem(self.env).reset_ticket_fields()
 
     def select(cls, env, db=None):
         if not db:
@@ -654,6 +660,7 @@
 
         if handle_ta:
             db.commit()
+        TicketSystem(self.env).reset_ticket_fields()
 
     def insert(self, db=None):
         assert self.name, 'Cannot create milestone with no name'
@@ -673,6 +680,7 @@
 
         if handle_ta:
             db.commit()
+        TicketSystem(self.env).reset_ticket_fields()
 
     def update(self, db=None):
         assert self.name, 'Cannot update milestone with no name'
@@ -698,6 +706,7 @@
 
         if handle_ta:
             db.commit()
+        TicketSystem(self.env).reset_ticket_fields()
 
     def select(cls, env, include_completed=True, db=None):
         if not db:
@@ -760,6 +769,7 @@
 
         if handle_ta:
             db.commit()
+        TicketSystem(self.env).reset_ticket_fields()
 
     def insert(self, db=None):
         assert not self.exists, 'Cannot insert existing version'
@@ -779,6 +789,7 @@
 
         if handle_ta:
             db.commit()
+        TicketSystem(self.env).reset_ticket_fields()
 
     def update(self, db=None):
         assert self.exists, 'Cannot update non-existent version'
@@ -804,6 +815,7 @@
 
         if handle_ta:
             db.commit()
+        TicketSystem(self.env).reset_ticket_fields()
 
     def select(cls, env, db=None):
         if not db:

