Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Docs Menu
Docs Home
/ / /
PyMongo Driver
/

Migrate to PyMongo Async

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.

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.

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

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

TestFindManyAndEmptyCursor

74.074 MB/s

112.490 MB/s

TestFindManyAndEmptyCursor80Tasks

37.181 MB/s

89.521 MB/s

TestFindManyAndEmptyCursor8Tasks

63.145 MB/s

97.165 MB/s

TestFindOneByID

3.121 MB/s

2.922 MB/s

TestFindOneByID80Tasks

3.789 MB/s

4.071 MB/s

TestFindOneByID8Tasks

3.697 MB/s

3.445 MB/s

TestFindOneByIDUnlimitedTasks

3.866 MB/s

4.171 MB/s

TestGridFsDownload

573.770 MB/s

603.578 MB/s

TestGridFsUpload

430.870 MB/s

444.445 MB/s

TestLargeDocBulkInsert

82.631 MB/s

102.105 MB/s

TestLargeDocClientBulkInsert

75.057 MB/s

90.345 MB/s

TestLargeDocCollectionBulkInsert

85.810 MB/s

101.838 MB/s

TestLargeDocInsertOne

84.832 MB/s

101.934 MB/s

TestLargeDocInsertOneUnlimitedTasks

120.389 MB/s

163.553 MB/s

TestRunCommand

0.036 MB/s

0.034 MB/s

TestRunCommand80Tasks

0.042 MB/s

0.043 MB/s

TestRunCommand8Tasks

0.039 MB/s

0.041 MB/s

TestRunCommandUnlimitedTasks

0.043 MB/s

0.042 MB/s

TestSmallDocBulkInsert

35.071 MB/s

38.213 MB/s

TestSmallDocBulkMixedOps

0.729 MB/s

0.446 MB/s

TestSmallDocClientBulkInsert

25.032 MB/s

25.727 MB/s

TestSmallDocClientBulkMixedOps

1.746 MB/s

1.723 MB/s

TestSmallDocCollectionBulkInsert

34.144 MB/s

37.666 MB/s

TestSmallDocInsertOne

0.539 MB/s

0.572 MB/s

TestSmallDocInsertOneUnlimitedTasks

0.740 MB/s

0.786 MB/s

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.

The following Motor method signatures behave differently in the PyMongo Async API:

  • AsyncMongoClient.__init__() does not accept an io_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. Use to_list(None) instead.

  • MongoClient is thread safe and can be used by many threads, however, an AsyncMongoClient 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.

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 with AsyncMongoClient.

  • 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 asynchronous cursor.to_list() method.

  • The AsyncCollection.find() method in the PyMongo Async API is synchronous, but returns an AsyncCursor. To iterate through the cursor, you must use an async for loop.

  • The AsyncMongoClient object does not support the connect 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

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.

To learn more about asynchronous Python, see the Python asyncio documentation.

Back

Upgrade Guides

On this page