@@ -18,20 +18,29 @@ Migrate to {+driver-async+}
1818.. meta::
1919 :keywords: motor, async, refactor, migration, asynchronous
2020
21- .. include:: /includes/pymongo-async-experimental.rst
22-
2321Overview
2422--------
2523
26- The {+driver-async+} driver is a unification of {+driver-short+} and the `Motor
24+ The {+driver-async+} API is a unification of {+driver-short+} and the `Motor
2725library <https://www.mongodb.com/docs/drivers/motor/>`__. In this guide, you can
2826identify the changes you must make to migrate an application from {+driver-short+} or
29- Motor to the {+driver-async+} driver.
27+ Motor to the {+driver-async+} API.
28+
29+ Motivation
30+ ~~~~~~~~~~
31+
32+ The {+driver-async+} API is designed to be a replacement for the Motor
33+ library. Motor was created to provide support for Tornado, with asyncio support
34+ added later. Because of this, Motor provides full asyncio and Tornado support,
35+ but still relies on a thread pool to perform network operations. In some cases,
36+ this might lead to performance degradation when using the Motor library. To
37+ address this issue, the {+driver-async+} API includes asyncio support directly
38+ into {+driver-short+}.
3039
3140Synchronous Versus Asynchronous
3241~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3342
34- To determine whether to migrate to the {+driver-async+} driver or to continue using
43+ To determine whether to migrate to the {+driver-async+} API or to continue using
3544Synchronous {+driver-short+}, consider the information in this section.
3645
3746Synchronous {+driver-short+} is preferable if the following criteria applies to your
@@ -45,7 +54,7 @@ application or use case:
4554
4655- You prefer the simplicity of synchronous logic when debugging your application
4756
48- Consider migrating to the {+driver-async+} driver if the following criteria applies
57+ Consider migrating to the {+driver-async+} API if the following criteria applies
4958to your application or use case:
5059
5160- Your application implements large, highly concurrent workloads (on the order of
@@ -56,19 +65,187 @@ to your application or use case:
5665
5766- Your application relies on other asynchronous libraries or frameworks, such as FastAPI
5867
68+ Performance Benchmarks
69+ ~~~~~~~~~~~~~~~~~~~~~~
70+
71+ The following table shows the performance benchmarks for different tasks
72+ performed with the {+driver-async+} API and the Motor library. Each task was
73+ performed with 10 iterations of 1000 documents each.
74+
75+ .. list-table::
76+ :header-rows: 1
77+ :widths: 20 40 40
78+
79+ * - Operation
80+ - Motor Performance
81+ - {+driver-async+} Performance
82+
83+ * - ``TestFindManyAndEmptyCursor``
84+ - 74.074 MB/s
85+ - 112.490 MB/s
86+
87+ * - ``TestFindManyAndEmptyCursor80Tasks``
88+ - 37.181 MB/s
89+ - 89.521 MB/s
90+
91+ * - ``TestFindManyAndEmptyCursor8Tasks``
92+ - 63.145 MB/s
93+ - 97.165 MB/s
94+
95+ * - ``TestFindOneByID``
96+ - 3.121 MB/s
97+ - 2.922 MB/s
98+
99+ * - ``TestFindOneByID80Tasks``
100+ - 3.789 MB/s
101+ - 4.071 MB/s
102+
103+ * - ``TestFindOneByID8Tasks``
104+ - 3.697 MB/s
105+ - 3.445 MB/s
106+
107+ * - ``TestFindOneByIDUnlimitedTasks``
108+ - 3.866 MB/s
109+ - 4.171 MB/s
110+
111+ * - ``TestGridFsDownload``
112+ - 573.770 MB/s
113+ - 603.578 MB/s
114+
115+ * - ``TestGridFsUpload``
116+ - 430.870 MB/s
117+ - 444.445 MB/s
118+
119+ * - ``TestLargeDocBulkInsert``
120+ - 82.631 MB/s
121+ - 102.105 MB/s
122+
123+ * - ``TestLargeDocClientBulkInsert``
124+ - 75.057 MB/s
125+ - 90.345 MB/s
126+
127+ * - ``TestLargeDocCollectionBulkInsert``
128+ - 85.810 MB/s
129+ - 101.838 MB/s
130+
131+ * - ``TestLargeDocInsertOne``
132+ - 84.832 MB/s
133+ - 101.934 MB/s
134+
135+ * - ``TestLargeDocInsertOneUnlimitedTasks``
136+ - 120.389 MB/s
137+ - 163.553 MB/s
138+
139+ * - ``TestRunCommand``
140+ - 0.036 MB/s
141+ - 0.034 MB/s
142+
143+ * - ``TestRunCommand80Tasks``
144+ - 0.042 MB/s
145+ - 0.043 MB/s
146+
147+ * - ``TestRunCommand8Tasks``
148+ - 0.039 MB/s
149+ - 0.041 MB/s
150+
151+ * - ``TestRunCommandUnlimitedTasks``
152+ - 0.043 MB/s
153+ - 0.042 MB/s
154+
155+ * - ``TestSmallDocBulkInsert``
156+ - 35.071 MB/s
157+ - 38.213 MB/s
158+
159+ * - ``TestSmallDocBulkMixedOps``
160+ - 0.729 MB/s
161+ - 0.446 MB/s
162+
163+ * - ``TestSmallDocClientBulkInsert``
164+ - 25.032 MB/s
165+ - 25.727 MB/s
166+
167+ * - ``TestSmallDocClientBulkMixedOps``
168+ - 1.746 MB/s
169+ - 1.723 MB/s
170+
171+ * - ``TestSmallDocCollectionBulkInsert``
172+ - 34.144 MB/s
173+ - 37.666 MB/s
174+
175+ * - ``TestSmallDocInsertOne``
176+ - 0.539 MB/s
177+ - 0.572 MB/s
178+
179+ * - ``TestSmallDocInsertOneUnlimitedTasks``
180+ - 0.740 MB/s
181+ - 0.786 MB/s
182+
183+ **Motor**
184+
185+ TestFindManyAndEmptyCursor 74.074 MB/s
186+ TestFindManyAndEmptyCursor80Tasks 37.181 MB/s
187+ TestFindManyAndEmptyCursor8Tasks 63.145 MB/s
188+ TestFindOneByID 3.121 MB/s
189+ TestFindOneByID80Tasks 3.789 MB/s
190+ TestFindOneByID8Tasks 3.697 MB/s
191+ TestFindOneByIDUnlimitedTasks 3.866 MB/s
192+ TestGridFsDownload 573.770 MB/s
193+ TestGridFsUpload 430.870 MB/s
194+ TestLargeDocBulkInsert 82.631 MB/s
195+ TestLargeDocClientBulkInsert 75.057 MB/s
196+ TestLargeDocCollectionBulkInsert 85.810 MB/s
197+ TestLargeDocInsertOne 84.832 MB/s
198+ TestLargeDocInsertOneUnlimitedTasks 120.389 MB/s
199+ TestRunCommand 0.036 MB/s
200+ TestRunCommand80Tasks 0.042 MB/s
201+ TestRunCommand8Tasks 0.039 MB/s
202+ TestRunCommandUnlimitedTasks 0.043 MB/s
203+ TestSmallDocBulkInsert 35.071 MB/s
204+ TestSmallDocBulkMixedOps 0.729 MB/s
205+ TestSmallDocClientBulkInsert 25.032 MB/s
206+ TestSmallDocClientBulkMixedOps 1.746 MB/s
207+ TestSmallDocCollectionBulkInsert 34.144 MB/s
208+ TestSmallDocInsertOne 0.539 MB/s
209+ TestSmallDocInsertOneUnlimitedTasks 0.740 MB/s
210+
211+ {+driver-async+}
212+
213+ TestFindManyAndEmptyCursor 112.490 MB/s
214+ TestFindManyAndEmptyCursor8Tasks 97.165 MB/s
215+ TestFindManyAndEmptyCursor80Tasks 89.521 MB/s
216+ TestFindOneByID 2.922 MB/s
217+ TestFindOneByID8Tasks 3.445 MB/s
218+ TestFindOneByID80Tasks 4.071 MB/s
219+ TestFindOneByIDUnlimitedTasks 4.171 MB/s
220+ TestGridFsDownload 603.578 MB/s
221+ TestGridFsUpload 444.445 MB/s
222+ TestLargeDocBulkInsert 102.105 MB/s
223+ TestLargeDocClientBulkInsert 90.345 MB/s
224+ TestLargeDocCollectionBulkInsert 101.838 MB/s
225+ TestLargeDocInsertOne 101.934 MB/s
226+ TestLargeDocInsertOneUnlimitedTasks 163.553 MB/s
227+ TestRunCommand 0.034 MB/s
228+ TestRunCommand8Tasks 0.041 MB/s
229+ TestRunCommand80Tasks 0.043 MB/s
230+ TestRunCommandUnlimitedTasks 0.042 MB/s
231+ TestSmallDocBulkInsert 38.213 MB/s
232+ TestSmallDocBulkMixedOps 0.446 MB/s
233+ TestSmallDocClientBulkInsert 25.727 MB/s
234+ TestSmallDocClientBulkMixedOps 1.723 MB/s
235+ TestSmallDocCollectionBulkInsert 37.666 MB/s
236+ TestSmallDocInsertOne 0.572 MB/s
237+ TestSmallDocInsertOneUnlimitedTasks 0.786 MB/s
238+
59239Migrate From Motor
60240------------------
61241
62242.. warning:: Motor Deprecation
63-
64- The {+driver-async+} driver is experimental. We do **not** recommend using it
65- in production environments.
66243
67244 Motor will be deprecated one year after the **production release** of the
68- {+driver-async+} driver . We strongly recommend that Motor users migrate to
69- the {+driver-async+} driver while Motor is still supported.
245+ {+driver-async+} API . We strongly recommend that Motor users migrate to
246+ the {+driver-async+} API while Motor is still supported.
70247
71- The {+driver-async+} driver functions similarly to the Motor library, but allows
248+ The {+driver-async+} API functions similarly to the Motor library, but allows
72249for improved latency and throughput due to directly using Python Asyncio instead
73250of delegating work to a thread pool. In most cases, you can directly migrate
74251existing Motor applications to {+driver-async+} by using ``AsyncMongoClient`` in
@@ -87,26 +264,26 @@ read and write operations in Motor compared to {+driver-async+}:
87264 from pymongo import AsyncMongoClient
88265
89266To see a list of the asynchronous methods available in the {+driver-async+}
90- driver , see the :ref:`pymongo-async-methods` section. To learn about the versions of Motor
267+ API , see the :ref:`pymongo-async-methods` section. To learn about the versions of Motor
91268that correspond to {+driver-short+}, see the :ref:`pymongo-motor-compatibility` section of
92269the Compatibility guide.
93270
94271The following section shows the method signature changes that you must implement
95- in your application when migrating from Motor to the {+driver-async+} driver .
272+ in your application when migrating from Motor to the {+driver-async+} API .
96273
97274.. warning::
98275
99- The {+driver-async+} driver does not support Tornado.
276+ The {+driver-async+} API does not support Tornado.
100277
101278Method Signature Changes
102279~~~~~~~~~~~~~~~~~~~~~~~~
103280
104- The following Motor method signatures behave differently in the {+driver-async+} driver :
281+ The following Motor method signatures behave differently in the {+driver-async+} API :
105282
106283- ``AsyncMongoClient.__init__()`` does not accept an ``io_loop`` parameter.
107- - ``AsyncCursor.each()`` does not exist in the {+driver-async+} driver .
108- - ``MotorGridOut.stream_to_handler()`` does not exist in the {+driver-async+} driver .
109- - ``AsyncCursor.to_list(0)`` is not valid in the {+driver-async+} driver . Use
284+ - ``AsyncCursor.each()`` does not exist in the {+driver-async+} api-root .
285+ - ``MotorGridOut.stream_to_handler()`` does not exist in the {+driver-async+} API .
286+ - ``AsyncCursor.to_list(0)`` is not valid in the {+driver-async+} API . Use
110287 ``to_list(None)`` instead.
111288- ``MongoClient`` is thread safe and can be used by many threads, however, an
112289 ``AsyncMongoClient`` is not thread safe and should only be used by a single
@@ -115,13 +292,13 @@ The following Motor method signatures behave differently in the {+driver-async+}
115292.. warning::
116293
117294 Motor users may experience a degradation of performance when switching to the
118- {+driver-async+} driver . This is due to the {+driver-async+} driver using native
295+ {+driver-async+} API . This is due to the {+driver-async+} API using native
119296 ``asyncio`` tasks instead of thread-based executors. Thread-based executors
120297 have similar performance characteristics to the synchronous driver, but slower.
121298 This means they perform better for workloads that do not fit the preceding criteria
122- for the {+driver-async+} driver .
299+ for the {+driver-async+} API .
123300
124- If you are experiencing performance slowdown, identify whether the {+driver-async+} driver
301+ If you are experiencing performance slowdown, identify whether the {+driver-async+} API
125302 is necessary for your usecase. If you determine your use case is better served by
126303 synchronous {+driver-short+}, consider using the synchronous driver
127304 with ``asyncio.loop.run_in_executor()`` for asynchronous compatibility. To learn more, see
@@ -132,7 +309,7 @@ The following Motor method signatures behave differently in the {+driver-async+}
132309Migrate from {+driver-short+}
133310-----------------------------
134311
135- The {+driver-async+} driver behaves similarly to {+driver-short+}, but
312+ The {+driver-async+} API behaves similarly to {+driver-short+}, but
136313all methods that perform network operations are coroutines and must be awaited.
137314To migrate from {+driver-short+} to {+driver-async+}, you must update your code
138315in the following ways:
@@ -142,11 +319,11 @@ in the following ways:
142319- If you call an asynchronous method inside a function, mark the function as ``async``.
143320
144321Keep the following points in mind when migrating from synchronous {+driver-short+}
145- to the {+driver-async+} driver :
322+ to the {+driver-async+} API :
146323
147324- To convert an ``AsyncCursor`` to a list, you must use the asynchronous ``cursor.to_list()``
148325 method.
149- - The ``AsyncCollection.find()`` method in the {+driver-async+} driver is synchronous, but
326+ - The ``AsyncCollection.find()`` method in the {+driver-async+} API is synchronous, but
150327 returns an ``AsyncCursor``. To iterate through the cursor, you must use an ``async for``
151328 loop.
152329- The ``AsyncMongoClient`` object does not support the ``connect`` keyword argument.
@@ -163,7 +340,7 @@ to the {+driver-async+} driver:
163340Asynchronous Methods
164341--------------------
165342
166- For a complete list of asynchronous methods available in the {+driver-async+} driver ,
343+ For a complete list of asynchronous methods available in the {+driver-async+} API ,
167344see the `API documentation <{+api-root+}pymongo/asynchronous/index.html>`__.
168345
169346.. note::
0 commit comments