@@ -18,20 +18,31 @@ Migrate to {+driver-async+}
18
18
.. meta::
19
19
:keywords: motor, async, refactor, migration, asynchronous
20
20
21
- .. include:: /includes/pymongo-async-experimental.rst
22
-
23
21
Overview
24
22
--------
25
23
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
27
25
library <https://www.mongodb.com/docs/drivers/motor/>`__. In this guide, you can
28
26
identify 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 implements ``asyncio`` support directly
38
+ into {+driver-short+}. In most cases, the {+driver-async+} API results in
39
+ improved performance over Motor. To see performance benchmarks, see the
40
+ :ref:`pymongo-async-benchmarks` section.
30
41
31
42
Synchronous Versus Asynchronous
32
43
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33
44
34
- To determine whether to migrate to the {+driver-async+} driver or to continue using
45
+ To determine whether to migrate to the {+driver-async+} API or to continue using
35
46
Synchronous {+driver-short+}, consider the information in this section.
36
47
37
48
Synchronous {+driver-short+} is preferable if the following criteria applies to your
@@ -45,7 +56,7 @@ application or use case:
45
56
46
57
- You prefer the simplicity of synchronous logic when debugging your application
47
58
48
- Consider migrating to the {+driver-async+} driver if the following criteria applies
59
+ Consider migrating to the {+driver-async+} API if the following criteria applies
49
60
to your application or use case:
50
61
51
62
- Your application implements large, highly concurrent workloads (on the order of
@@ -56,20 +67,134 @@ to your application or use case:
56
67
57
68
- Your application relies on other asynchronous libraries or frameworks, such as FastAPI
58
69
70
+ .. _pymongo-async-benchmarks:
71
+
72
+ Performance Benchmarks
73
+ ~~~~~~~~~~~~~~~~~~~~~~
74
+
75
+ The following table shows the performance benchmarks for different tasks
76
+ performed with the {+driver-async+} API and the Motor library. Each task was
77
+ performed with 10 iterations of 1000 documents each. In most
78
+ cases, the {+driver-async+} API results in improved performance over Motor.
79
+
80
+ .. list-table::
81
+ :header-rows: 1
82
+ :widths: 40 20 20
83
+
84
+ * - Operation
85
+ - Motor Performance
86
+ - {+driver-async+} Performance
87
+
88
+ * - ``TestFindManyAndEmptyCursor``
89
+ - 74.074 MB/s
90
+ - 112.490 MB/s
91
+
92
+ * - ``TestFindManyAndEmptyCursor80Tasks``
93
+ - 37.181 MB/s
94
+ - 89.521 MB/s
95
+
96
+ * - ``TestFindManyAndEmptyCursor8Tasks``
97
+ - 63.145 MB/s
98
+ - 97.165 MB/s
99
+
100
+ * - ``TestFindOneByID``
101
+ - 3.121 MB/s
102
+ - 2.922 MB/s
103
+
104
+ * - ``TestFindOneByID80Tasks``
105
+ - 3.789 MB/s
106
+ - 4.071 MB/s
107
+
108
+ * - ``TestFindOneByID8Tasks``
109
+ - 3.697 MB/s
110
+ - 3.445 MB/s
111
+
112
+ * - ``TestFindOneByIDUnlimitedTasks``
113
+ - 3.866 MB/s
114
+ - 4.171 MB/s
115
+
116
+ * - ``TestGridFsDownload``
117
+ - 573.770 MB/s
118
+ - 603.578 MB/s
119
+
120
+ * - ``TestGridFsUpload``
121
+ - 430.870 MB/s
122
+ - 444.445 MB/s
123
+
124
+ * - ``TestLargeDocBulkInsert``
125
+ - 82.631 MB/s
126
+ - 102.105 MB/s
127
+
128
+ * - ``TestLargeDocClientBulkInsert``
129
+ - 75.057 MB/s
130
+ - 90.345 MB/s
131
+
132
+ * - ``TestLargeDocCollectionBulkInsert``
133
+ - 85.810 MB/s
134
+ - 101.838 MB/s
135
+
136
+ * - ``TestLargeDocInsertOne``
137
+ - 84.832 MB/s
138
+ - 101.934 MB/s
139
+
140
+ * - ``TestLargeDocInsertOneUnlimitedTasks``
141
+ - 120.389 MB/s
142
+ - 163.553 MB/s
143
+
144
+ * - ``TestRunCommand``
145
+ - 0.036 MB/s
146
+ - 0.034 MB/s
147
+
148
+ * - ``TestRunCommand80Tasks``
149
+ - 0.042 MB/s
150
+ - 0.043 MB/s
151
+
152
+ * - ``TestRunCommand8Tasks``
153
+ - 0.039 MB/s
154
+ - 0.041 MB/s
155
+
156
+ * - ``TestRunCommandUnlimitedTasks``
157
+ - 0.043 MB/s
158
+ - 0.042 MB/s
159
+
160
+ * - ``TestSmallDocBulkInsert``
161
+ - 35.071 MB/s
162
+ - 38.213 MB/s
163
+
164
+ * - ``TestSmallDocBulkMixedOps``
165
+ - 0.729 MB/s
166
+ - 0.446 MB/s
167
+
168
+ * - ``TestSmallDocClientBulkInsert``
169
+ - 25.032 MB/s
170
+ - 25.727 MB/s
171
+
172
+ * - ``TestSmallDocClientBulkMixedOps``
173
+ - 1.746 MB/s
174
+ - 1.723 MB/s
175
+
176
+ * - ``TestSmallDocCollectionBulkInsert``
177
+ - 34.144 MB/s
178
+ - 37.666 MB/s
179
+
180
+ * - ``TestSmallDocInsertOne``
181
+ - 0.539 MB/s
182
+ - 0.572 MB/s
183
+
184
+ * - ``TestSmallDocInsertOneUnlimitedTasks``
185
+ - 0.740 MB/s
186
+ - 0.786 MB/s
187
+
59
188
Migrate From Motor
60
189
------------------
61
190
62
191
.. warning:: Motor Deprecation
63
-
64
- The {+driver-async+} driver is experimental. We do **not** recommend using it
65
- in production environments.
66
192
67
- 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.
193
+ Motor will be deprecated on May 14th, 2026. We strongly recommend that Motor users migrate to
194
+ the {+driver-async+} API while Motor is still supported.
70
195
71
- The {+driver-async+} driver functions similarly to the Motor library, but allows
72
- for improved latency and throughput due to directly using Python Asyncio instead
196
+ The {+driver-async+} API functions similarly to the Motor library, but allows
197
+ for improved latency and throughput due to directly using Python ``asyncio`` instead
73
198
of delegating work to a thread pool. In most cases, you can directly migrate
74
199
existing Motor applications to {+driver-async+} by using ``AsyncMongoClient`` in
75
200
place of ``MotorClient``, and changing the application's import statements to
@@ -87,26 +212,22 @@ read and write operations in Motor compared to {+driver-async+}:
87
212
from pymongo import AsyncMongoClient
88
213
89
214
To 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
215
+ API , see the :ref:`pymongo-async-methods` section. To learn about the versions of Motor
91
216
that correspond to {+driver-short+}, see the :ref:`pymongo-motor-compatibility` section of
92
217
the Compatibility guide.
93
218
94
219
The following section shows the method signature changes that you must implement
95
- in your application when migrating from Motor to the {+driver-async+} driver.
96
-
97
- .. warning::
98
-
99
- The {+driver-async+} driver does not support Tornado.
220
+ in your application when migrating from Motor to the {+driver-async+} API.
100
221
101
222
Method Signature Changes
102
223
~~~~~~~~~~~~~~~~~~~~~~~~
103
224
104
- The following Motor method signatures behave differently in the {+driver-async+} driver :
225
+ The following Motor method signatures behave differently in the {+driver-async+} API :
105
226
106
227
- ``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
228
+ - ``AsyncCursor.each()`` does not exist in the {+driver-async+} API .
229
+ - ``MotorGridOut.stream_to_handler()`` does not exist in the {+driver-async+} API .
230
+ - ``AsyncCursor.to_list(0)`` is not valid in the {+driver-async+} API . Use
110
231
``to_list(None)`` instead.
111
232
- ``MongoClient`` is thread safe and can be used by many threads, however, an
112
233
``AsyncMongoClient`` is not thread safe and should only be used by a single
@@ -115,13 +236,13 @@ The following Motor method signatures behave differently in the {+driver-async+}
115
236
.. warning::
116
237
117
238
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
239
+ {+driver-async+} API . This is due to the {+driver-async+} API using native
119
240
``asyncio`` tasks instead of thread-based executors. Thread-based executors
120
241
have similar performance characteristics to the synchronous driver, but slower.
121
242
This means they perform better for workloads that do not fit the preceding criteria
122
- for the {+driver-async+} driver .
243
+ for the {+driver-async+} API .
123
244
124
- If you are experiencing performance slowdown, identify whether the {+driver-async+} driver
245
+ If you are experiencing performance slowdown, identify whether the {+driver-async+} API
125
246
is necessary for your usecase. If you determine your use case is better served by
126
247
synchronous {+driver-short+}, consider using the synchronous driver
127
248
with ``asyncio.loop.run_in_executor()`` for asynchronous compatibility. To learn more, see
@@ -132,7 +253,7 @@ The following Motor method signatures behave differently in the {+driver-async+}
132
253
Migrate from {+driver-short+}
133
254
-----------------------------
134
255
135
- The {+driver-async+} driver behaves similarly to {+driver-short+}, but
256
+ The {+driver-async+} API behaves similarly to {+driver-short+}, but
136
257
all methods that perform network operations are coroutines and must be awaited.
137
258
To migrate from {+driver-short+} to {+driver-async+}, you must update your code
138
259
in the following ways:
@@ -142,11 +263,11 @@ in the following ways:
142
263
- If you call an asynchronous method inside a function, mark the function as ``async``.
143
264
144
265
Keep the following points in mind when migrating from synchronous {+driver-short+}
145
- to the {+driver-async+} driver :
266
+ to the {+driver-async+} API :
146
267
147
268
- To convert an ``AsyncCursor`` to a list, you must use the asynchronous ``cursor.to_list()``
148
269
method.
149
- - The ``AsyncCollection.find()`` method in the {+driver-async+} driver is synchronous, but
270
+ - The ``AsyncCollection.find()`` method in the {+driver-async+} API is synchronous, but
150
271
returns an ``AsyncCursor``. To iterate through the cursor, you must use an ``async for``
151
272
loop.
152
273
- The ``AsyncMongoClient`` object does not support the ``connect`` keyword argument.
@@ -163,7 +284,7 @@ to the {+driver-async+} driver:
163
284
Asynchronous Methods
164
285
--------------------
165
286
166
- For a complete list of asynchronous methods available in the {+driver-async+} driver ,
287
+ For a complete list of asynchronous methods available in the {+driver-async+} API ,
167
288
see the `API documentation <{+api-root+}pymongo/asynchronous/index.html>`__.
168
289
169
290
.. note::
@@ -173,5 +294,5 @@ see the `API documentation <{+api-root+}pymongo/asynchronous/index.html>`__.
173
294
Additional Information
174
295
----------------------
175
296
176
- To learn more about asynchronous Python, see the `Python Asyncio documentation
297
+ To learn more about asynchronous Python, see the `Python asyncio documentation
177
298
<https://docs.python.org/3/library/asyncio.html>`__.
0 commit comments