diff --git a/django/db/models/query.py b/django/db/models/query.py
index 4e786a239e..8ee1b34117 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -565,7 +565,17 @@ class QuerySet:
         if id_list is not None:
             if not id_list:
                 return {}
-            qs = self.filter(pk__in=id_list).order_by()
+            batch_size = connections[self.db].features.max_query_params
+            id_list = tuple(id_list)
+            # If the database has a limit on the number of query parameters
+            # (e.g. SQLite), retrieve objects in batches if necessary.
+            if batch_size and batch_size < len(id_list):
+                qs = ()
+                for offset in range(0, len(id_list), batch_size):
+                    batch = id_list[offset:offset + batch_size]
+                    qs += tuple(self.filter(pk__in=batch).order_by())
+            else:
+                qs = self.filter(pk__in=id_list).order_by()
         else:
             qs = self._clone()
         return {obj._get_pk_val(): obj for obj in qs}
diff --git a/tests/lookup/tests.py b/tests/lookup/tests.py
index f826a480a1..25098af03c 100644
--- a/tests/lookup/tests.py
+++ b/tests/lookup/tests.py
@@ -1,8 +1,10 @@
 import collections
 from datetime import datetime
+from math import ceil
 from operator import attrgetter
 
 from django.core.exceptions import FieldError
+from django.db import connection
 from django.test import TestCase, skipUnlessDBFeature
 
 from .models import Article, Author, Game, Player, Season, Tag
@@ -127,6 +129,15 @@ class LookupTests(TestCase):
         with self.assertRaises(TypeError):
             Article.objects.in_bulk(headline__startswith='Blah')
 
+    def test_in_bulk_lots_of_ids(self):
+        test_range = 2000
+        max_query_params = connection.features.max_query_params
+        expected_num_queries = ceil(test_range / max_query_params) if max_query_params else 1
+        Author.objects.bulk_create([Author() for i in range(test_range - Author.objects.count())])
+        authors = {author.pk: author for author in Author.objects.all()}
+        with self.assertNumQueries(expected_num_queries):
+            self.assertEqual(Author.objects.in_bulk(authors.keys()), authors)
+
     def test_values(self):
         # values() returns a list of dictionaries instead of object instances --
         # and you can specify which fields you want to retrieve.