diff --git a/django/contrib/postgres/indexes.py b/django/contrib/postgres/indexes.py
index 9ff66c2a00..7c687987db 100644
--- a/django/contrib/postgres/indexes.py
+++ b/django/contrib/postgres/indexes.py
@@ -33,5 +33,27 @@ class BrinIndex(Index):
 class GinIndex(Index):
     suffix = 'gin'
 
+    def __init__(self, fields=[], name=None, fastupdate=None, gin_pending_list_limit=None):
+        self.fastupdate = fastupdate
+        self.gin_pending_list_limit = gin_pending_list_limit
+        super().__init__(fields, name)
+
+    def deconstruct(self):
+        path, args, kwargs = super().deconstruct()
+        kwargs['fastupdate'] = self.fastupdate
+        kwargs['gin_pending_list_limit'] = self.gin_pending_list_limit
+        return path, args, kwargs
+
+    def get_sql_create_template_values(self, model, schema_editor, using):
+        parameters = super().get_sql_create_template_values(model, schema_editor, using=' USING gin')
+        with_params = []
+        if self.gin_pending_list_limit is not None:
+            with_params.append('gin_pending_list_limit = %d' % self.gin_pending_list_limit)
+        if self.fastupdate is not None:
+            with_params.append('fastupdate = {}'.format('on' if self.fastupdate else 'off'))
+        if with_params:
+            parameters['extra'] = 'WITH ({}) {}'.format(', '.join(with_params), parameters['extra'])
+        return parameters
+
     def create_sql(self, model, schema_editor):
         return super().create_sql(model, schema_editor, using=' USING gin')
diff --git a/django/db/backends/postgresql/features.py b/django/db/backends/postgresql/features.py
index 44c48eb946..3f6cc7894d 100644
--- a/django/db/backends/postgresql/features.py
+++ b/django/db/backends/postgresql/features.py
@@ -48,3 +48,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
     @cached_property
     def has_jsonb_agg(self):
         return self.connection.pg_version >= 90500
+
+    @cached_property
+    def has_gin_pending_list_limit(self):
+        return self.connection.pg_version >= 90500
diff --git a/docs/ref/contrib/postgres/indexes.txt b/docs/ref/contrib/postgres/indexes.txt
index ce5a50caf3..e364f8d83e 100644
--- a/docs/ref/contrib/postgres/indexes.txt
+++ b/docs/ref/contrib/postgres/indexes.txt
@@ -22,7 +22,7 @@ available from the ``django.contrib.postgres.indexes`` module.
 ``GinIndex``
 ============
 
-.. class:: GinIndex()
+.. class:: GinIndex(fields=[], name=None, fastupdate=None, gin_pending_list_limit=None)
 
     Creates a `gin index
     <https://www.postgresql.org/docs/current/static/gin.html>`_.
@@ -34,3 +34,17 @@ available from the ``django.contrib.postgres.indexes`` module.
     PostgreSQL. You can install it using the
     :class:`~django.contrib.postgres.operations.BtreeGinExtension` migration
     operation.
+
+    Set the ``fastupdate`` parameter to ``False`` to disable the `GIN Fast
+    Update Technique`_ that's enabled by default in PostgreSQL.
+
+    Provide an integer number of bytes to the gin_pending_list_limit_ parameter
+    to tune the maximum size of the GIN pending list which is used when
+    ``fastupdate`` is enabled. This parameter requires PostgreSQL ≥ 9.5.
+
+    .. _GIN Fast Update Technique: https://www.postgresql.org/docs/current/static/gin-implementation.html#GIN-FAST-UPDATE
+    .. _gin_pending_list_limit: https://www.postgresql.org/docs/current/static/runtime-config-client.html#GUC-GIN-PENDING-LIST-LIMIT
+
+    .. versionchanged:: 2.0
+
+        The ``fastupdate`` and ``gin_pending_list_limit`` parameters were added.
diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt
index 70a21d3da6..5170e66cbe 100644
--- a/docs/releases/2.0.txt
+++ b/docs/releases/2.0.txt
@@ -108,6 +108,9 @@ Minor features
   :class:`~django.contrib.postgres.operations.CryptoExtension` migration
   operation.
 
+* :class:`django.contrib.postgres.indexes.GinIndex` now supports the
+  ``fast_update`` and ``gin_pending_list_limit`` parameters.
+
 :mod:`django.contrib.redirects`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/tests/postgres_tests/test_indexes.py b/tests/postgres_tests/test_indexes.py
index c3172f3a49..d866a8b869 100644
--- a/tests/postgres_tests/test_indexes.py
+++ b/tests/postgres_tests/test_indexes.py
@@ -65,11 +65,24 @@ class GinIndexTests(PostgreSQLTestCase):
         self.assertEqual(index.name, 'postgres_te_field_def2f8_gin')
 
     def test_deconstruction(self):
-        index = GinIndex(fields=['title'], name='test_title_gin')
+        index = GinIndex(
+            fields=['title'],
+            name='test_title_gin',
+            fastupdate=True,
+            gin_pending_list_limit=128,
+        )
         path, args, kwargs = index.deconstruct()
         self.assertEqual(path, 'django.contrib.postgres.indexes.GinIndex')
         self.assertEqual(args, ())
-        self.assertEqual(kwargs, {'fields': ['title'], 'name': 'test_title_gin'})
+        self.assertEqual(
+            kwargs,
+            {
+                'fields': ['title'],
+                'name': 'test_title_gin',
+                'fastupdate': True,
+                'gin_pending_list_limit': 128,
+            }
+        )
 
 
 class SchemaTests(PostgreSQLTestCase):
@@ -97,6 +110,31 @@ class SchemaTests(PostgreSQLTestCase):
             editor.remove_index(IntegerArrayModel, index)
         self.assertNotIn(index_name, self.get_constraints(IntegerArrayModel._meta.db_table))
 
+    def test_gin_fastupdate(self):
+        index_name = 'integer_array_gin_fastupdate'
+        index = GinIndex(fields=['field'], name=index_name, fastupdate=False)
+        with connection.schema_editor() as editor:
+            editor.add_index(IntegerArrayModel, index)
+        constraints = self.get_constraints(IntegerArrayModel._meta.db_table)
+        self.assertEqual(constraints[index_name]['type'], 'gin')
+        self.assertEqual(constraints[index_name]['options'], ['fastupdate=off'])
+        with connection.schema_editor() as editor:
+            editor.remove_index(IntegerArrayModel, index)
+        self.assertNotIn(index_name, self.get_constraints(IntegerArrayModel._meta.db_table))
+
+    @skipUnlessDBFeature('has_gin_pending_list_limit')
+    def test_gin_parameters(self):
+        index_name = 'integer_array_gin_params'
+        index = GinIndex(fields=['field'], name=index_name, fastupdate=True, gin_pending_list_limit=64)
+        with connection.schema_editor() as editor:
+            editor.add_index(IntegerArrayModel, index)
+        constraints = self.get_constraints(IntegerArrayModel._meta.db_table)
+        self.assertEqual(constraints[index_name]['type'], 'gin')
+        self.assertEqual(constraints[index_name]['options'], ['gin_pending_list_limit=64', 'fastupdate=on'])
+        with connection.schema_editor() as editor:
+            editor.remove_index(IntegerArrayModel, index)
+        self.assertNotIn(index_name, self.get_constraints(IntegerArrayModel._meta.db_table))
+
     @skipUnlessDBFeature('has_brin_index_support')
     def test_brin_index(self):
         index_name = 'char_field_model_field_brin'