> For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

<!--
Tab options on this page. Append to the .md URL to filter:
  ?tabs=<id,...>   select specific tabs (e.g. ?tabs=nodejs,shell)
  ?allTabs=true    include every tab
  (no param)       default: one tab per tabset

Available tabs:
  other tabs: sync, async
-->

# Customize Server Selection

## Overview

All MongoDB drivers follow a defined algorithm when selecting a server to read or write from. By using the `server_selector` property of `MongoClient`, you can customize this algorithm to choose the server that works best for your application.

**Important:**

Customizing the server-selection algorithm can have unintended consequences, such as degraded read or write performance.

## Customized Selection Algorithm

When PyMongo executes a read operation, it performs the following steps, in order, to select a MongoDB deployment:

1. From the list of known servers, PyMongo selects all servers that match the active read preference.

2. If at least one readable server exists, PyMongo calls the user-defined server-selector function and passes in the list from the previous step.

3. PyMongo applies the `localThresholdMS` connection setting to the list of servers returned from the function.

4. PyMongo selects a server at random from the servers still on the list and executes the operation against this server.

When PyMongo executes a write operation, it begins by selecting all writeable servers, not just those that match the active read preference. The remaining steps are identical.

To learn more about the default server-selection algorithm, which the driver follows when you don't use the `server_selector` argument, see [Server Selection Algorithm](https://www.mongodb.com/docs/manual/core/read-preference-mechanics/) in the MongoDB Server manual.

## Example: Select Servers on `localhost`

When using a sharded cluster with multiple `mongos` servers, you might want to prefer deployments running on `localhost`. Operations against these deployments usually have lower latency and higher throughput. This example shows how to customize the server-selection algorithm to favor servers running on `localhost`.

First, write a Python function to select your preferred servers. The server-selection function must meet the following criteria:

- Accepts a list of `ServerDescription` objects as a parameter

- Returns the list of `ServerDescription` objects suitable for the read or write operation

- Doesn't create or modify any `ServerDescription` objects

The following example defines a function named `prefer_local` that accepts and returns a list of `ServerDescription` objects:

```python
def prefer_local(server_descriptions):
    ...
    return servers  # list containing preferred servers
```

Next, implement your server-selection logic in the function body. You can use any property defined in the `ServerDescription` class to select your preferred servers. To return only MongoDB deployments running on `localhost`, this example loops on the servers in `server_descriptions` and checks the `address` property of each server for the value `"localhost"`:

```python
def prefer_local(server_descriptions):
    servers = [
        server for server in server_descriptions if server.address[0] == "localhost"
    ]
    return servers
```

Next, consider the case when your algorithm finds no matching servers. If your function returns an empty list, your application can't communicate with MongoDB. Therefore, return a list containing at least one `ServerDescription` object from your function.

In this example, if no matching server is found, the `prefer_local` function returns the list of servers originally passed as an argument:

```python
def prefer_local(server_descriptions):
    servers = [
        server for server in server_descriptions if server.address[0] == "localhost"
    ]

    if not servers:
        return server_descriptions
    return servers
```

Finally, instruct PyMongo to use your function. To do so, call the `MongoClient` constructor and pass the `server_selector` argument with your function name as the value. Select the Synchronous or Asynchronous tab to see the corresponding code:

### Synchronous

```python
client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname>:<port>",
                             server_selector=prefer_local)
```

## API Documentation

For more information about customizing PyMongo's server-selection algorithm, see the following API documentation:

- [MongoClient](https://pymongo.readthedocs.io/en/4.19.0/api/pymongo/mongo_client.html#pymongo.mongo_client.MongoClient)

- [ServerDescription](https://pymongo.readthedocs.io/en/4.19.0/api/pymongo/server_description.html#pymongo.server_description.ServerDescription)
