diff --git a/docs/src/userguide/extension_types.rst b/docs/src/userguide/extension_types.rst
index 9bf803310aad6441a164a42f0e625096137a23e8..7e56fb141fd974955efec75438d3b4abebfd05ae 100644
--- a/docs/src/userguide/extension_types.rst
+++ b/docs/src/userguide/extension_types.rst
@@ -39,14 +39,14 @@ interface to them.
 
 .. _readonly:
 
-Attributes
-============
+Static Attributes
+=================
 
 Attributes of an extension type are stored directly in the object's C struct.
 The set of attributes is fixed at compile time; you can't add attributes to an
 extension type instance at run time simply by assigning to them, as you could
 with a Python class instance. (You can subclass the extension type in Python
-and add attributes to instances of the subclass, however.)
+and add attributes to instances of the subclass, see :ref:`dynamic_attributes`.)
 
 There are two ways that attributes of an extension type can be accessed: by
 Python attribute lookup, or by direct access to the C struct from Cython code.
@@ -76,6 +76,51 @@ and the depth attribute readable but not writable.
     Python access, not direct access. All the attributes of an extension type
     are always readable and writable by C-level access.
 
+
+.. _dynamic_attributes:
+
+Dynamic Attributes
+==================
+
+It is not possible to add attributes to an extension type at runtime by default.
+You have two ways of avoiding this limitation, both add an overhead when
+a method is called from Python code.
+
+The first workaround is making a child Python class and is preferred way of
+keeping the static attributes of an extension
+type while enabling the use of dynamic attributes::
+
+    cdef class Animal:
+
+        cdef int number_of_legs
+        def __cinit__(self, int number_of_legs):
+            self.number_of_legs = number_of_legs
+
+
+    class ExtendableAnimal(Animal):  # Note that we use class, not cdef class
+        pass
+
+
+    dog = ExtendableAnimal(4)
+    dog.has_tail = True
+
+
+Declaring a ``__dict__`` attribute is the second way of enabling dynamic attributes
+and can have a significant performance penalty compared to subclassing,
+especially when using ``cpdef`` class methods::
+
+    cdef class Animal:
+
+        cdef int number_of_legs
+        cdef dict __dict__
+        def __cinit__(self, int number_of_legs):
+            self.number_of_legs = number_of_legs
+
+
+    dog = Animal(4)
+    dog.has_tail = True
+
+
 Type declarations
 ===================