MongoDB Performance
# MongoDB Performance

As you develop and operate applications with MongoDB, you may need to analyze the performance of the application and its database. When you encounter degraded performance, it is often a function of database access strategies, hardware availability, and the number of open database connections.

Some users may experience performance limitations as a result of inadequate or inappropriate indexing strategies, or as a consequence of poor schema design patterns. Locking Performance discusses how these can impact MongoDB's internal locking.

Performance issues may indicate that the database is operating at capacity and that it is time to add additional capacity to the database. In particular, the application's working set should fit in the available physical memory.

In some cases performance issues may be temporary and related to abnormal traffic load. As discussed in Number of Connections, scaling can help relax excessive traffic.

Database profiling can help you to understand what operations are causing degradation.

## Locking Performance
Database profiling can help you to understand what operations are causing degradation.

## Locking Performance

MongoDB uses a locking system to ensure data set consistency. If certain operations are long-running or a queue forms, performance will degrade as requests and operations wait for the lock.

Lock-related slowdowns can be intermittent. To see if the lock has been affecting your performance, refer to the locks section and the globalLock section of the `serverStatus` output.

Dividing `locks.<type>.timeAcquiringMicros` by `locks.<type>.acquireWaitCount` can give an approximate average wait time for a particular lock mode.

`locks.<type>.deadlockCount` provide the number of times the lock acquisitions encountered deadlocks.

If `globalLock.currentQueue.total` is consistently high, then there is a chance that a large number of requests are waiting for a lock. This indicates a possible concurrency issue that may be affecting performance.
If `globalLock.totalTime` is high relative to `uptime`, the database has existed in a lock state for a significant amount of time.

Long queries can result from ineffective use of indexes; non-optimal schema design; poor query structure; system architecture issues; or insufficient RAM resulting in disk reads.

## Number of Connections

In some cases, the number of connections between the applications and the database can overwhelm the ability of the server to handle requests. The following fields in the `serverStatus` document can provide insight:

- `connections` is a container for the following two fields:

  - `connections.current` the total number of current clients connected to the database instance.

  - `connections.available` the total number of unused connections available for new clients.

If there are numerous concurrent application requests, the database may have trouble keeping up with demand. If this is the case, increase the capacity of your deployment.
For write-heavy applications, deploy sharding and add one or more shards to a sharded cluster to distribute load among `mongod` instances.

Spikes in the number of connections can also be the result of application or driver errors. All of the officially supported MongoDB drivers implement connection pooling, which allows clients to use and reuse connections more efficiently. An extremely high number of connections, particularly without corresponding workload, is often indicative of a driver or other configuration error.

Unless constrained by system-wide limits, the maximum number of incoming connections supported by MongoDB is configured with the `maxIncomingConnections` setting. On Unix-based systems, system-wide limits can be modified using the `ulimit` command, or by editing your system's `/etc/sysctl` file. See UNIX `ulimit` Settings for more information.

## Full Time Diagnostic Data Capture
## Full Time Diagnostic Data Capture

To help MongoDB engineers analyze server behavior, `mongod` and `mongos` processes include a Full Time Diagnostic Data Capture (FTDC) mechanism. FTDC is enabled by default. Due to its importance in debugging deployments, FTDC thread failures are fatal and stop the parent `mongod` or `mongos` process.

FTDC data files are compressed and not human-readable. They inherit the same file access permissions as the MongoDB data files. Only users with access to FTDC data files can transmit the FTDC data.

MongoDB engineers cannot access FTDC data without explicit permission and assistance from system owners or operators.

FTDC data **never** contains any of the following information:

- Samples of queries, query predicates, or query results

- Data sampled from any end-user collection or index

- System or MongoDB user credentials or security certificates
- Data sampled from any end-user collection or index

- System or MongoDB user credentials or security certificates

FTDC data contains certain host machine information such as hostnames, operating system information, and the options or settings used to start the `mongod` or `mongos`. This information may be considered protected or confidential by some organizations or regulatory bodies, but is not typically considered to be Personally Identifiable Information (PII). For clusters where these fields are configured with protected, confidential, or PII data, please notify MongoDB engineers before sending FTDC data to coordinate appropriate security measures.

On Windows, to collect system data such as disk, cpu, and memory, FTDC requires Microsoft access permissions from the following groups:

- Performance Monitor Users

- Performance Log Users

If the user running `mongod` and `mongos` is not an administrator, add them to these groups to log FTDC data. For more information, see the Microsoft documentation here.
FTDC periodically collects statistics produced by the following commands:

- `serverStatus`

- `replSetGetStatus` (`mongod` only)

- `collStats` for the `local.oplog.rs` collection (`mongod` only)

- `connPoolStats` (`mongos` only)

Depending on the host operating system, the diagnostic data may include one or more of the following utilization statistics:

- CPU utilization

- Memory utilization

- Disk utilization related to performance. FTDC does not include data related to storage capacity.

- Network performance statistics. FTDC only captures metadata and does not capture or inspect any network packets.
- Network performance statistics. FTDC only captures metadata and does not capture or inspect any network packets.

If the `mongod` process runs in a container, FTDC reports utilization statistics from the perspective of the container instead of the host operating system. For example, if a the `mongod` runs in a container that is configured with RAM restrictions, FTDC calculates memory utilization against the container's RAM limit, as opposed to the host operating system's RAM limit.

FTDC collects statistics produced by the following commands on file rotation or startup:

- `getCmdLineOpts`

- `buildInfo`

- `hostInfo`

`mongod` processes store FTDC data files in a `diagnostic.data` directory under the instances `storage.dbPath`. All diagnostic data files are stored under this directory. For example, given a `dbPath` of `/data/db`, the diagnostic data directory would be `/data/db/diagnostic.data`.
`mongos` processes store FTDC data files in a diagnostic directory relative to the `systemLog.path` log path setting. MongoDB truncates the logpath's file extension and concatenates `diagnostic.data` to the remaining name. For example, given a `path` setting of `/var/log/mongodb/mongos.log`, the diagnostic data directory would be `/var/log/mongodb/mongos.diagnostic.data`.

You can view the FTDC source code on the MongoDB Github Repository. The `ftdc_system_stats_*.ccp` files specifically define any system-specific diagnostic data captured.

FTDC runs with the following defaults:

- Data capture every 1 second

- 200MB maximum `diagnostic.data` folder size.

These defaults are designed to provide useful data to MongoDB engineers with minimal impact on performance or storage size. These values only require modifications if requested by MongoDB engineers for specific diagnostic purposes.
To disable FTDC, start up the `mongod` or `mongos` with the `diagnosticDataCollectionEnabled: false` option in the `setParameter` settings of your configuration file:

```yaml
setParameter:
  diagnosticDataCollectionEnabled: false
```

Disabling FTDC may increase the time or resources required when analyzing or debugging issues with support from MongoDB engineers. For information on MongoDB Support, visit Get Started With MongoDB Support.