Migrate to PyMongo Async
Overview
The PyMongo Async API is a unification of PyMongo and the Motor library. In this guide, you can identify the changes you must make to migrate an application from PyMongo or Motor to the PyMongo Async API.
Motivation
The PyMongo Async API is designed to be a replacement for the Motor
library. Motor was created to provide support for Tornado, with asyncio
support
added later. Because of this, Motor provides full asyncio
and Tornado support,
but still relies on a thread pool to perform network operations. In some cases,
this might lead to performance degradation when using the Motor library. To
address this issue, the PyMongo Async API implements asyncio
support directly
into PyMongo. In most cases, the PyMongo Async API results in
improved performance over Motor. To see performance benchmarks, see the
Performance Benchmarks section.
Synchronous Versus Asynchronous
To determine whether to migrate to the PyMongo Async API or to continue using Synchronous PyMongo, consider the information in this section.
Synchronous PyMongo is preferable if the following criteria applies to your application or use case:
Your application is simple in execution, or you prefer to avoid using asynchronous calls in your code
Your application relies on serial workloads or workloads with very fast response times
You prefer the simplicity of synchronous logic when debugging your application
Consider migrating to the PyMongo Async API if the following criteria applies to your application or use case:
Your application implements large, highly concurrent workloads (on the order of thousands of concurrent operations)
Your application relies on workloads that spend a long time waiting for responses or writing data
Your application relies on other asynchronous libraries or frameworks, such as FastAPI
Performance Benchmarks
The following table shows the performance benchmarks for different tasks performed with the PyMongo Async API and the Motor library. Each task was performed with 10 iterations of 1000 documents each. In most cases, the PyMongo Async API results in improved performance over Motor.
Operation | Motor Performance | PyMongo Async Performance |
---|---|---|
| 74.074 MB/s | 112.490 MB/s |
| 37.181 MB/s | 89.521 MB/s |
| 63.145 MB/s | 97.165 MB/s |
| 3.121 MB/s | 2.922 MB/s |
| 3.789 MB/s | 4.071 MB/s |
| 3.697 MB/s | 3.445 MB/s |
| 3.866 MB/s | 4.171 MB/s |
| 573.770 MB/s | 603.578 MB/s |
| 430.870 MB/s | 444.445 MB/s |
| 82.631 MB/s | 102.105 MB/s |
| 75.057 MB/s | 90.345 MB/s |
| 85.810 MB/s | 101.838 MB/s |
| 84.832 MB/s | 101.934 MB/s |
| 120.389 MB/s | 163.553 MB/s |
| 0.036 MB/s | 0.034 MB/s |
| 0.042 MB/s | 0.043 MB/s |
| 0.039 MB/s | 0.041 MB/s |
| 0.043 MB/s | 0.042 MB/s |
| 35.071 MB/s | 38.213 MB/s |
| 0.729 MB/s | 0.446 MB/s |
| 25.032 MB/s | 25.727 MB/s |
| 1.746 MB/s | 1.723 MB/s |
| 34.144 MB/s | 37.666 MB/s |
| 0.539 MB/s | 0.572 MB/s |
| 0.740 MB/s | 0.786 MB/s |
Migrate From Motor
Warning
Motor Deprecation
Motor will be deprecated on May 14th, 2026. We strongly recommend that Motor users migrate to the PyMongo Async API while Motor is still supported.
The PyMongo Async API functions similarly to the Motor library, but allows
for improved latency and throughput due to directly using Python asyncio
instead
of delegating work to a thread pool. In most cases, you can directly migrate
existing Motor applications to PyMongo Async by using AsyncMongoClient
in
place of MotorClient
, and changing the application's import statements to
import from pymongo
.
The following example shows the difference in imports to use a client for read and write operations in Motor compared to PyMongo Async:
# Motor client import from motor.motor_asyncio import AsyncIOMotorClient # PyMongo Async client import from pymongo import AsyncMongoClient
To see a list of the asynchronous methods available in the PyMongo Async API, see the Asynchronous Methods section. To learn about the versions of Motor that correspond to PyMongo, see the Motor Compatibility section of the Compatibility guide.
The following section shows the method signature changes that you must implement in your application when migrating from Motor to the PyMongo Async API.
Method Signature Changes
The following Motor method signatures behave differently in the PyMongo Async API:
AsyncMongoClient.__init__()
does not accept anio_loop
parameter.AsyncCursor.each()
does not exist in the PyMongo Async API.MotorGridOut.stream_to_handler()
does not exist in the PyMongo Async API.AsyncCursor.to_list(0)
is not valid in the PyMongo Async API. Useto_list(None)
instead.MongoClient
is thread safe and can be used by many threads, however, anAsyncMongoClient
is not thread safe and should only be used by a single event loop.
Warning
Motor users may experience a degradation of performance when switching to the
PyMongo Async API. This is due to the PyMongo Async API using native
asyncio
tasks instead of thread-based executors. Thread-based executors
have similar performance characteristics to the synchronous driver, but slower.
This means they perform better for workloads that do not fit the preceding criteria
for the PyMongo Async API.
If you are experiencing performance slowdown, identify whether the PyMongo Async API
is necessary for your usecase. If you determine your use case is better served by
synchronous PyMongo, consider using the synchronous driver
with asyncio.loop.run_in_executor()
for asynchronous compatibility. To learn more, see
the Event Loop API documentation.
Migrate from PyMongo
The PyMongo Async API behaves similarly to PyMongo, but all methods that perform network operations are coroutines and must be awaited. To migrate from PyMongo to PyMongo Async, you must update your code in the following ways:
Replace all uses of
MongoClient
withAsyncMongoClient
.Add the
await
keyword to all asynchronous method calls.If you call an asynchronous method inside a function, mark the function as
async
.
Keep the following points in mind when migrating from synchronous PyMongo to the PyMongo Async API:
To convert an
AsyncCursor
to a list, you must use the asynchronouscursor.to_list()
method.The
AsyncCollection.find()
method in the PyMongo Async API is synchronous, but returns anAsyncCursor
. To iterate through the cursor, you must use anasync for
loop.The
AsyncMongoClient
object does not support theconnect
keyword argument.You cannot share
AsyncMongoClient
objects across threads or event loops.To access a property or method of a result returned by an asynchronous call, you must properly wrap the call in parentheses, as shown in the following example:
id = (await posts.insert_one(doc)).inserted_id
Asynchronous Methods
For a complete list of asynchronous methods available in the PyMongo Async API, see the API documentation.
Note
Any methods not listed in the preceding API documentation are synchronous.
Additional Information
To learn more about asynchronous Python, see the Python asyncio documentation.