---
title: Measure performance
description: DS directory servers offer high throughput and low response times for most operations. DS software includes the following command-line tools for measuring performance of common LDAP operations:
component: pingds
version: 8.1
page_id: pingds:getting-started:performance
canonical_url: https://docs.pingidentity.com/pingds/8.1/getting-started/performance.html
revdate: 2025-10-22T14:42:39Z
keywords: ["Evaluation", "Performance", "LDAP"]
section_ids:
  perfs-mods: Measure modification rates
  perfs-searches: Measure search rates
  perfs-check-repl: Check replication
---

# Measure performance

DS directory servers offer high throughput and low response times for most operations. DS software includes the following command-line tools for measuring performance of common LDAP operations:

* `addrate` measures LDAP adds and deletes

* `authrate` measures LDAP binds

* `modrate` measures LDAP modifications

* `searchrate` measures LDAP searches

|   |                                                                                                                                                                                                                                                                                                                               |
| - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Before trying the examples that follow, work through the previous examples. You should have two directory server replicas running on your local computer, as described in [Learn replication](replication.html):![Two replicated DS servers with a client application running a performance tool](../_images/performance.png) |

The following examples show how to measure and verify basic directory performance. For a deeper dive into the subject, read [Performance tuning](../config-guide/tuning.html).

## Measure modification rates

In deployment, you can expect many directory client applications to change directory data in parallel. The directory has to serve all these requests with high throughput (lots of requests) and low latency (quick responses), so all the client applications can get their work done quickly.

As a first step towards tuning your directory service performance, get a sense of the throughput and response times you can expect by measuring the LDAP modification rate with the `modrate` command:

* Bash

* PowerShell

* Zsh

```shell
# Run modrate for 10 seconds against the first server:
modrate \
 --maxDuration 10 \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDn uid=kvaughan,ou=People,dc=example,dc=com \
 --bindPassword bribery \
 --noRebind \
 --numConnections 4 \
 --numConcurrentRequests 4 \
 --targetDn "uid=user.{1},ou=people,dc=example,dc=com" \
 --argument "rand(0,100000)" \
 --argument "randstr(16)" \
 "description:{2}"

# Read number of modify requests on the LDAPS port:
ldapsearch \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=monitor \
 --bindPassword password \
 --baseDN "cn=LDAPS,cn=connection handlers,cn=monitor" \
 "(&)" \
 ds-mon-requests-modify
```

```powershell
# Run modrate for 10 seconds against the first server, and observe the performance numbers:
modrate.bat `
 --maxDuration 10 `
 --hostname localhost `
 --port 1636 `
 --useSsl `
 --trustStorePath C:\path\to\opendj\config\
 --trustStoreType PKCS12 \keystore `
 --trustStorePassword:file C:\path\to\opendj\config\keystore.pin `
 --bindDn uid=kvaughan,ou=People,dc=example,dc=com `
 --bindPassword bribery `
 --noRebind `
 --numConnections 4 `
 --numConcurrentRequests 4 `
 --targetDn "uid=user.{1},ou=people,dc=example,dc=com" `
 --argument "rand(0,100000)" `
 --argument "randstr(16)" `
 "description:{2}"

# Read number of modify requests on the LDAPS port:
ldapsearch.bat `
 --hostname localhost `
 --port 1636 `
 --useSsl `
 --trustStorePath C:\path\to\opendj\config\
 --trustStoreType PKCS12 \keystore `
 --trustStorePassword:file C:\path\to\opendj\config\keystore.pin `
 --bindDN uid=monitor `
 --bindPassword password `
 --baseDN "cn=LDAPS,cn=connection handlers,cn=monitor" `
 "(objectclass=*)" `
 ds-mon-requests-modify
```

```shell
# Run modrate for 10 seconds against the first server:
modrate \
 --maxDuration 10 \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDn uid=kvaughan,ou=People,dc=example,dc=com \
 --bindPassword bribery \
 --noRebind \
 --numConnections 4 \
 --numConcurrentRequests 4 \
 --targetDn "uid=user.{1},ou=people,dc=example,dc=com" \
 --argument "rand(0,100000)" \
 --argument "randstr(16)" \
 "description:{2}"

# Read number of modify requests on the LDAPS port:
ldapsearch \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=monitor \
 --bindPassword password \
 --baseDN "cn=LDAPS,cn=connection handlers,cn=monitor" \
 "(&)" \
 ds-mon-requests-modify
```

When reading the `modrate` command output, notice that it shows statistics for throughput (operations/second), response times (milliseconds), and errors/second. If you expect all operations to succeed and yet `err/sec` is not 0.0, the command options are no doubt incorrectly set. For an explanation of the command output, refer to [modrate](../tools-reference/modrate.html).

Notice that the monitoring attributes hold similar, alternative statistics.

## Measure search rates

Your directory service exists to hold identity data and to make it easy and quick to find. Almost all directory client applications search the directory. Some applications, such as those providing naming services or those in a call path, require very low latency.

To get a sense of the throughput and response times you can expect from your directory even before you tune performance, measure the LDAP search rate with the `searchrate` command:

* Bash

* PowerShell

* Zsh

```shell
# Run searchrate for 10 seconds against the first server:
searchrate \
 --maxDuration 10 \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDn uid=bjensen,ou=People,dc=example,dc=com \
 --bindPassword hifalutin \
 --noRebind \
 --numConnections 4 \
 --numConcurrentRequests 4 \
 --baseDn "dc=example,dc=com" \
 --argument "rand(0,100000)" \
 "(uid=user.{})"

# Read number of subtree search requests on the LDAPS port:
ldapsearch \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=monitor \
 --bindPassword password \
 --baseDN "cn=LDAPS,cn=connection handlers,cn=monitor" \
 "(&)" \
 ds-mon-requests-search-sub
```

```powershell
# Run searchrate for 10 seconds against the first server:
searchrate.bat `
 --maxDuration 10 `
 --hostname localhost `
 --port 1636 `
 --useSsl `
 --trustStorePath C:\path\to\opendj\config\
 --trustStoreType PKCS12 \keystore `
 --trustStorePassword:file C:\path\to\opendj\config\keystore.pin `
 --bindDn uid=bjensen,ou=People,dc=example,dc=com `
 --bindPassword password `
 --noRebind `
 --numConnections 4 `
 --numConcurrentRequests 4 `
 --baseDn "dc=example,dc=com" `
 --argument "rand(0,100000)" `
 "(uid=user.{})"

# Read number of subtree search requests on the LDAPS port:
ldapsearch.bat `
 --hostname localhost `
 --port 1636 `
 --useSsl `
 --trustStorePath C:\path\to\opendj\config\
 --trustStoreType PKCS12 \keystore `
 --trustStorePassword:file C:\path\to\opendj\config\keystore.pin `
 --bindDN uid=monitor `
 --bindPassword password `
 --baseDN "cn=LDAPS,cn=connection handlers,cn=monitor" `
 "(objectclass=*)" `
 ds-mon-requests-search-sub
```

```shell
# Run searchrate for 10 seconds against the first server:
searchrate \
 --maxDuration 10 \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDn uid=bjensen,ou=People,dc=example,dc=com \
 --bindPassword hifalutin \
 --noRebind \
 --numConnections 4 \
 --numConcurrentRequests 4 \
 --baseDn "dc=example,dc=com" \
 --argument "rand(0,100000)" \
 "(uid=user.{})"

# Read number of subtree search requests on the LDAPS port:
ldapsearch \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=monitor \
 --bindPassword password \
 --baseDN "cn=LDAPS,cn=connection handlers,cn=monitor" \
 "(&)" \
 ds-mon-requests-search-sub
```

Notice that `searchrate` command output resembles that of the `modrate` command. The `searchrate` output also indicates how many entries each search returned. For an explanation of the command output, refer to [searchrate](../tools-reference/searchrate.html).

## Check replication

When you measured directory performance, the `modrate` command made many changes to user's entries. Replication between your two DS replicas should replay each change so client applications get the same response regardless of which replica they use to read a user's entry.

Check the data on both replicas is synchronized. The following example uses monitoring metrics to check replication delay is zero on each replica:

* Bash

* PowerShell

* Zsh

```console
$ ldapsearch \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=monitor \
 --bindPassword password \
 --baseDN cn=monitor \
 "(ds-mon-current-delay=*)" \
 ds-mon-current-delay
```

> **Collapse: Show output**
>
> ```
> dn: ds-mon-domain-name=cn=schema,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-server-id=second-ds,cn=remote replicas,ds-mon-domain-name=cn=schema,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-domain-name=dc=example\,dc=com,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-server-id=second-ds,cn=remote replicas,ds-mon-domain-name=dc=example\,dc=com,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-domain-name=uid=monitor,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-server-id=second-ds,cn=remote replicas,ds-mon-domain-name=uid=monitor,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
> ```

```powershell
ldapsearch.bat `
 --hostname localhost `
 --port 1636 `
 --useSsl `
 --trustStorePath C:\path\to\opendj\config\
 --trustStoreType PKCS12 \keystore `
 --trustStorePassword:file C:\path\to\opendj\config\keystore.pin `
 --bindDN uid=monitor `
 --bindPassword password `
 --baseDN cn=monitor `
 "(ds-mon-current-delay=*)" `
 ds-mon-current-delay
```

> **Collapse: Show output**
>
> ```
> dn: ds-mon-domain-name=cn=schema,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-server-id=second-ds,cn=remote replicas,ds-mon-domain-name=cn=schema,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-domain-name=dc=example\,dc=com,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-server-id=second-ds,cn=remote replicas,ds-mon-domain-name=dc=example\,dc=com,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-domain-name=uid=monitor,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-server-id=second-ds,cn=remote replicas,ds-mon-domain-name=uid=monitor,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
> ```

```console
$ ldapsearch \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=monitor \
 --bindPassword password \
 --baseDN cn=monitor \
 "(ds-mon-current-delay=*)" \
 ds-mon-current-delay
```

> **Collapse: Show output**
>
> ```
> dn: ds-mon-domain-name=cn=schema,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-server-id=second-ds,cn=remote replicas,ds-mon-domain-name=cn=schema,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-domain-name=dc=example\,dc=com,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-server-id=second-ds,cn=remote replicas,ds-mon-domain-name=dc=example\,dc=com,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-domain-name=uid=monitor,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
>
> dn: ds-mon-server-id=second-ds,cn=remote replicas,ds-mon-domain-name=uid=monitor,cn=replicas,cn=replication,cn=monitor
> ds-mon-current-delay: 0
> ```
