> ## Documentation Index
> Fetch the complete documentation index at: https://developer.upsun.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MongoDB (Database service)

> MongoDB is a cross-platform, document-oriented database. For more information on using MongoDB, see MongoDB's own documentation.

export const DynamicCodeBlock = ({language = 'yaml', filename, icon, lines, wrap, expandable, highlight, focus, children}) => {
  const STORAGE_KEY = 'upsun_versions_cache';
  const COMPOSABLE_STORAGE_KEY = 'upsun_composable_cache';
  const CACHE_TTL = 5 * 60 * 1000;
  const API_URL = 'https://meta.upsun.com/images';
  const COMPOSABLE_API_URL = 'https://meta.upsun.com/composable';
  const DEBUG_PREFIX = '[DynamicCodeBlock cache]';
  const [versionData, setVersionData] = useState(null);
  const [versionError, setVersionError] = useState(false);
  const [composableData, setComposableData] = useState(null);
  const [composableError, setComposableError] = useState(false);
  useEffect(() => {
    const fetchData = async () => {
      let cachedData = null;
      let cachedEtag = null;
      if (typeof localStorage !== 'undefined') {
        try {
          const cached = localStorage.getItem(STORAGE_KEY);
          if (cached) {
            const parsed = JSON.parse(cached);
            cachedData = parsed?.data || null;
            cachedEtag = parsed?.etag || null;
            if (cachedData && Date.now() - parsed.timestamp < CACHE_TTL) {
              return cachedData;
            }
          }
        } catch (err) {
          console.error('Failed to load from cache:', err);
        }
      }
      const requestHeaders = cachedEtag ? {
        'If-None-Match': cachedEtag
      } : {};
      console.debug(`${DEBUG_PREFIX} revalidating`, {
        storageKey: STORAGE_KEY,
        hasCachedData: Boolean(cachedData),
        hasCachedEtag: Boolean(cachedEtag)
      });
      const response = await fetch(API_URL, {
        headers: requestHeaders
      });
      if (response.status === 304 && cachedData) {
        console.debug(`${DEBUG_PREFIX} revalidated (304)`, {
          storageKey: STORAGE_KEY
        });
        if (typeof localStorage !== 'undefined') {
          try {
            const etag = response.headers.get('etag') || cachedEtag;
            localStorage.setItem(STORAGE_KEY, JSON.stringify({
              data: cachedData,
              etag,
              timestamp: Date.now()
            }));
          } catch (err) {
            console.error('Failed to refresh cache metadata:', err);
          }
        }
        return cachedData;
      }
      if (!response.ok) throw new Error(`API request failed: ${response.statusText}`);
      const data = await response.json();
      const etag = response.headers.get('etag');
      console.debug(`${DEBUG_PREFIX} refreshed (200)`, {
        storageKey: STORAGE_KEY,
        etag
      });
      if (typeof localStorage !== 'undefined') {
        try {
          localStorage.setItem(STORAGE_KEY, JSON.stringify({
            data,
            etag,
            timestamp: Date.now()
          }));
        } catch (err) {
          console.error('Failed to cache data:', err);
        }
      }
      return data;
    };
    fetchData().then(data => setVersionData(data)).catch(err => console.error('Failed to fetch version data:', err));
  }, []);
  const findHighestVersion = versionsMap => {
    if (!versionsMap || Object.keys(versionsMap).length === 0) return null;
    const entries = Object.entries(versionsMap);
    const active = entries.filter(([, v]) => v.upsun && v.upsun.status === 'supported' || v.upsun && v.upsun.status === 'deprecated');
    const candidates = active.length > 0 ? active : entries;
    let [highestName] = candidates[0];
    for (let i = 1; i < candidates.length; i++) {
      const [currentName] = candidates[i];
      const cp = currentName.split('.').map(Number);
      const hp = highestName.split('.').map(Number);
      for (let j = 0; j < Math.max(cp.length, hp.length); j++) {
        if ((cp[j] || 0) > (hp[j] || 0)) {
          highestName = currentName;
          break;
        } else if ((cp[j] || 0) < (hp[j] || 0)) {
          break;
        }
      }
    }
    return highestName;
  };
  const getVersion = (lang, requestedVersion = 'latest') => {
    if (lang === 'composable') {
      if (!composableData || !composableData.versions || Object.keys(composableData.versions).length === 0) return null;
      if (requestedVersion && requestedVersion !== 'latest') {
        return (requestedVersion in composableData.versions) ? requestedVersion : null;
      }
      return findHighestVersion(composableData.versions);
    }
    if (!versionData) return null;
    const imageData = versionData[lang];
    if (!imageData || !imageData.versions || Object.keys(imageData.versions).length === 0) {
      return null;
    }
    if (requestedVersion && requestedVersion !== 'latest') {
      return (requestedVersion in imageData.versions) ? requestedVersion : null;
    }
    return findHighestVersion(imageData.versions);
  };
  let code = typeof children === 'string' ? children : String(children || '');
  const codeLines = code.split('\n');
  while (codeLines.length > 0 && codeLines[0].trim() === '') codeLines.shift();
  while (codeLines.length > 0 && codeLines[codeLines.length - 1].trim() === '') codeLines.pop();
  if (codeLines.length > 0) {
    const indents = codeLines.filter(line => line.trim().length > 0).map(line => line.match(/^[ \t]*/)[0].length);
    const minIndent = Math.min(...indents);
    code = codeLines.map(line => line.slice(minIndent)).join('\n');
  }
  code = code.replace(/\{\{version:(.*?)\}\}/g, (match, params) => {
    const parts = params.split(':');
    const lang = parts[0];
    const ver = parts[1] || 'latest';
    const isComposable = lang === 'composable';
    const hasError = isComposable ? composableError : versionError;
    const dataReady = isComposable ? composableData !== null : versionData !== null;
    if (hasError) return '(unavailable)';
    if (dataReady) {
      const resolvedVersion = getVersion(lang, ver);
      return resolvedVersion || match;
    }
    return '...';
  });
  const codeBlockProps = {
    language,
    ...filename && ({
      filename
    }),
    ...icon && ({
      icon
    }),
    ...lines !== undefined && ({
      lines
    }),
    ...wrap !== undefined && ({
      wrap
    }),
    ...expandable !== undefined && ({
      expandable
    }),
    ...highlight && ({
      highlight
    }),
    ...focus && ({
      focus
    })
  };
  return <CodeBlock {...codeBlockProps}>{code}</CodeBlock>;
};

## Enterprise edition

<Info>
  <h4>Premium Service</h4>
  MongoDB Enterprise isn’t included in any Upsun plan.
  You need to add it separately at an additional cost.
  To add MongoDB Enterprise, [contact Sales](https://upsun.com/contact-us/).
</Info>

### Supported versions

You can select the major and minor version.

Patch versions are applied periodically for bug fixes and the like.
When you deploy your app, you always get the latest available patches.

* <span class="runtime-version-badge" data-tooltip="version: 7.0.34">7.0</span>

### Deprecated versions

The following versions are still available in your projects,
but they're at their end of life and are no longer receiving security updates from upstream.

*No deprecated versions.*

To ensure your project remains stable in the future, switch to a [supported version](#supported-versions).

### Retired versions

The following versions have been retired and are no longer available.
If your project uses a retired version, you must update to a [supported version](#supported-versions).

* <span class="runtime-version-badge" data-tooltip="version: 6.0.28">6.0</span>
* <span class="runtime-version-badge" data-tooltip="version: 5.0.33">5.0</span>
* <span class="runtime-version-badge" data-tooltip="version: 4.4.30">4.4</span>
* <span class="runtime-version-badge" data-tooltip="version: 4.2.25">4.2</span>
* <span class="runtime-version-badge" data-tooltip="version: 4.0.28">4.0</span>

## Legacy edition

Previous non-Enterprise versions are available in your projects (and are listed below),
but they're at their [end of life](https://www.mongodb.com/support-policy/legacy)
and are no longer receiving security updates from upstream.

### Supported versions

You can select the major and minor version.

Patch versions are applied periodically for bug fixes and the like.
When you deploy your app, you always get the latest available patches.

* <span class="runtime-version-badge" data-tooltip="version: 4.0.3">4.0</span>

<Note>
  <h4>Warning</h4>
  Downgrades of MongoDB aren't supported.
  MongoDB updates its own data files to a new version automatically but can't downgrade them.
  If you want to experiment with a later version without committing to it use a preview environment.
</Note>

### Deprecated versions

The following versions are still available in your projects,
but they're at their end of life and are no longer receiving security updates from upstream.

*No deprecated versions.*

To ensure your project remains stable in the future, switch to a [supported version](#supported-versions).

### Retired versions

The following versions have been retired and are no longer available.
If your project uses a retired version, you must update to a [supported version](#supported-versions).

* <span class="runtime-version-badge" data-tooltip="version: 3.6.23">3.6</span>
* <span class="runtime-version-badge" data-tooltip="version: 3.4.24">3.4</span>
* <span class="runtime-version-badge" data-tooltip="version: 3.2.22">3.2</span>
* <span class="runtime-version-badge" data-tooltip="version: 3.0.15">3.0</span>

## Relationship reference

For each service [defined via a relationship](#usage-example) to your application,
Upsun automatically generates corresponding environment variables within your application container,
in the `$<RELATIONSHIP-NAME>_<SERVICE-PROPERTY>` format.

Here is example information available through the [service environment variables](/docs/development/variables#service-environment-variables) themselves,
or through the [`PLATFORM_RELATIONSHIPS` environment variable](/docs/development/variables/use-variables#use-provided-variables).

<Tabs>
  <Tab title="Service environment variables">
    You can obtain the complete list of available service environment variables in your app container by running `upsun ssh env`.

    Note that the information about the relationship can change when an app is redeployed or restarted or the relationship is changed. So your apps should only rely on the [service environment variables](/docs/development/variables#service-environment-variables) directly rather than hard coding any values.

    <DynamicCodeBlock language="bash">
      {`
              MONGODB_USERNAME=main
              MONGODB_SCHEME=mongodb
              MONGODB_SERVICE=mongodb
              MONGODB_IP=123.456.78.90
              MONGODB_HOSTNAME=azertyuiopqsdfghjklm.mongodb.service._.eu-1.platformsh.site
              MONGODB_CLUSTER=azertyuiop-main-7rqtwti
              MONGODB_HOST=mongodbdatabase.internal
              MONGODB_REL=mongodb
              MONGODB_QUERY={'is_master': True}
              MONGODB_PATH=main
              MONGODB_PASSWORD=
              MONGODB_TYPE=mongodb-enterprise:{{version:mongodb-enterprise:latest}}
              MONGODB_PORT=27017
            `
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="`PLATFORM_RELATIONSHIPS` environment variable">
    For some advanced use cases, you can use the [`PLATFORM_RELATIONSHIPS` environment variable](/docs/development/variables/use-variables#use-provided-variables).
    The structure of the `PLATFORM_RELATIONSHIPS` environment variable can be obtained by running `upsun relationships` in your terminal:

    <DynamicCodeBlock language="json">
      {`
              {
                "username": "main",
                "scheme": "mongodb",
                "service": "mongodb",
                "ip": "123.456.78.90",
                "hostname": "azertyuiopqsdfghjklm.mongodb.service._.eu-1.platformsh.site",
                "cluster": "azertyuiop-main-7rqtwti",
                "host": "mongodb.internal",
                "rel": "mongodb",
                "query": {
                  "is_master": true
                },
                "path": "main",
                "password": null,
                "type": "mongodb-enterprise:{{version:mongodb-enterprise:latest}}",
                "port": 27017
              }
            `
          }
    </DynamicCodeBlock>

    Here is an example of how to gather [`PLATFORM_RELATIONSHIPS` environment variable](/docs/development/variables/use-variables#use-provided-variables) information in a [`.environment` file](/docs/development/variables/set-variables#when-to-use-env-files):

    ```bash .environment theme={null}
    # Decode the built-in credentials object variable.
    export RELATIONSHIPS_JSON="$(echo "$PLATFORM_RELATIONSHIPS" | base64 --decode)"

    # Set environment variables for individual credentials.
    export APP_MONGODBDATABASE_HOST="$(echo "$RELATIONSHIPS_JSON" | jq -r '.mongodb[0].host')"
    ```
  </Tab>
</Tabs>

## Usage example

### Enterprise edition example

#### 1. Configure the service

To define the service, use the `mongodb-enterprise` type:

<DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
  {`
      services:
        # The name of the service container. Must be unique within a project.
        <SERVICE_NAME>:
          type: mongodb-enterprise:<VERSION>
    `
  }
</DynamicCodeBlock>

Note that changing the name of the service replaces it with a brand new service and all existing data is lost. Back up your data before changing the service.

#### 2. Define the relationship

To define the relationship, use the following configuration:

<Tabs>
  <Tab title="Using default endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                <APP_NAME>:
                  # Relationships enable access from this app to a given service.
                  # The example below shows simplified configuration leveraging a default service
                  # (identified from the relationship name) and a default endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    <SERVICE_NAME>:
            `
          }
    </DynamicCodeBlock>

    You can define `SERVICE_NAME` as you like, so long as it's unique between all defined services
    and matches in both the application and services configuration.

    The example above leverages [default endpoint](/docs/configure-apps/image-properties/relationships) configuration for relationships.
    That is, it uses default endpoints behind the scenes, providing a [relationship](/docs/configure-apps/image-properties/relationships)
    (the network address a service is accessible from) that is identical to the *name* of that service.

    Depending on your needs, instead of default endpoint configuration,
    you can use [explicit endpoint configuration](/docs/configure-apps/image-properties/relationships).

    With the above definition, the application container (`APP_NAME`) now has [access to the service](#use-in-app) via the relationship `SERVICE_NAME` and its corresponding [service environment variables](/docs/development/variables#service-environment-variables).
  </Tab>

  <Tab title="Using explicit endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                <APP_NAME>:
                  # Relationships enable access from this app to a given service.
                  # The example below shows configuration with an explicitly set service name and endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    <RELATIONSHIP_NAME>:
                      service: <SERVICE_NAME>
                      endpoint: mongodb
            `
          }
    </DynamicCodeBlock>

    You can define `SERVICE_NAME` and `<RELATIONSHIP_NAME>` as you like, so long as it's unique between all defined services and relationships
    and matches in both the application and services configuration.

    The example above leverages [explicit endpoint](/docs/configure-apps/image-properties/relationships) configuration for relationships.

    Depending on your needs, instead of explicit endpoint configuration,
    you can use [default endpoint configuration](/docs/configure-apps/image-properties/relationships).

    With the above definition, the application container now has [access to the service](#use-in-app) via the relationship `<RELATIONSHIP_NAME>` and its corresponding [service environment variables](/docs/development/variables#service-environment-variables).
  </Tab>
</Tabs>

For PHP, enable the [extension](/docs/languages/php/extensions) for the service:

<Tabs>
  <Tab title="Using default endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                <APP_NAME>:
                  # PHP extensions.
                  runtime:
                    extensions:
                      - mongodb
                  # Relationships enable access from this app to a given service.
                  # The example below shows simplified configuration leveraging a default service
                  # (identified from the relationship name) and a default endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    <SERVICE_NAME>:
            `
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Using explicit endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                <APP_NAME>:
                  # PHP extensions.
                  runtime:
                    extensions:
                      - mongodb
                  # Relationships enable access from this app to a given service.
                  # The example below shows configuration with an explicitly set service name and endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    <RELATIONSHIP_NAME>:
                      service: <SERVICE_NAME>
                      endpoint: mongodb
            `
          }
    </DynamicCodeBlock>
  </Tab>
</Tabs>

#### Example configuration

<Tabs>
  <Tab title="Using default endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # PHP extensions.
                  runtime:
                    extensions:
                      - mongodb
                  # Relationships enable access from this app to a given service.
                  # The example below shows simplified configuration leveraging a default service
                  # (identified from the relationship name) and a default endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    mongodb-enterprise:
              services:
                # The name of the service container. Must be unique within a project.
                mongodb-enterprise:
                  type: mongodb-enterprise:{{version:mongodb-enterprise:latest}}`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Using explicit endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # PHP extensions.
                  runtime:
                    extensions:
                      - mongodb
                  # Relationships enable access from this app to a given service.
                  # The example below shows configuration with an explicitly set service name and endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    mongodb-enterprise:
                      service: mongodb-enterprise
                      endpoint: mongodb
              services:
                # The name of the service container. Must be unique within a project.
                mongodb-enterprise:
                  type: mongodb-enterprise:{{version:mongodb-enterprise:latest}}`
          }
    </DynamicCodeBlock>
  </Tab>
</Tabs>

### Legacy edition example

#### 1. Configure the service

To define the service, use the `mongodb` type:

<DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
  {`
      services:
        # The name of the service container. Must be unique within a project.
        <SERVICE_NAME>:
          type: mongodb:<VERSION>
    `
  }
</DynamicCodeBlock>

Note that changing the name of the service replaces it with a brand new service and all existing data is lost. Back up your data before changing the service.

#### 2. Define the relationship

To define the relationship, use the following configuration:

<Tabs>
  <Tab title="Using default endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                <APP_NAME>:
                  # Relationships enable access from this app to a given service.
                  # The example below shows simplified configuration leveraging a default service
                  # (identified from the relationship name) and a default endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    <SERVICE_NAME>:
            `
          }
    </DynamicCodeBlock>

    You can define `SERVICE_NAME` as you like, so long as it's unique between all defined services
    and matches in both the application and services configuration.

    The example above leverages [default endpoint](/docs/configure-apps/image-properties/relationships) configuration for relationships.
    That is, it uses default endpoints behind the scenes, providing a [relationship](/docs/configure-apps/image-properties/relationships)
    (the network address a service is accessible from) that is identical to the *name* of that service.

    Depending on your needs, instead of default endpoint configuration,
    you can use [explicit endpoint configuration](/docs/configure-apps/image-properties/relationships).

    With the above definition, the application container (`APP_NAME`) now has [access to the service](#use-in-app) via the relationship `SERVICE_NAME` and its corresponding [service environment variables](/docs/development/variables#service-environment-variables).
  </Tab>

  <Tab title="Using explicit endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                <APP_NAME>:
                  # Relationships enable access from this app to a given service.
                  # The example below shows configuration with an explicitly set service name and endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    <RELATIONSHIP_NAME>:
                      service: <SERVICE_NAME>
                      endpoint: mongodb
            `
          }
    </DynamicCodeBlock>

    You can define `SERVICE_NAME` and `<RELATIONSHIP_NAME>` as you like, so long as it's unique between all defined services and relationships
    and matches in both the application and services configuration.

    The example above leverages [explicit endpoint](/docs/configure-apps/image-properties/relationships) configuration for relationships.

    Depending on your needs, instead of explicit endpoint configuration,
    you can use [default endpoint configuration](/docs/configure-apps/image-properties/relationships).

    With the above definition, the application container now has [access to the service](#use-in-app) via the relationship `<RELATIONSHIP_NAME>` and its corresponding [service environment variables](/docs/development/variables#service-environment-variables).
  </Tab>
</Tabs>

For PHP, enable the [extension](/docs/languages/php/extensions) for the service:

<Tabs>
  <Tab title="Using default endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                <APP_NAME>:
                  # PHP extensions.
                  runtime:
                    extensions:
                      - mongodb
                  # Relationships enable access from this app to a given service.
                  # The example below shows simplified configuration leveraging a default service
                  # (identified from the relationship name) and a default endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    <SERVICE_NAME>:
            `
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Using explicit endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                <APP_NAME>:
                  # PHP extensions.
                  runtime:
                    extensions:
                      - mongodb
                  # Relationships enable access from this app to a given service.
                  # The example below shows configuration with an explicitly set service name and endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    <RELATIONSHIP_NAME>:
                      service: <SERVICE_NAME>
                      endpoint: mongodb
            `
          }
    </DynamicCodeBlock>
  </Tab>
</Tabs>

#### Example configuration

<Tabs>
  <Tab title="Using default endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # PHP extensions.
                  runtime:
                    extensions:
                      - mongodb
                  # Relationships enable access from this app to a given service.
                  # The example below shows simplified configuration leveraging a default service
                  # (identified from the relationship name) and a default endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    mongodb:
              services:
                # The name of the service container. Must be unique within a project.
                mongodb:
                  type: mongodb:{{version:mongodb:latest}}
            `}
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Using explicit endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # PHP extensions.
                  runtime:
                    extensions:
                      - mongodb
                  # Relationships enable access from this app to a given service.
                  # The example below shows configuration with an explicitly set service name and endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    mongodb:
                      service: mongodb
                      endpoint: mongodb
              services:
                # The name of the service container. Must be unique within a project.
                mongodb:
                  type: mongodb:{{version:mongodb:latest}}
            `}
    </DynamicCodeBlock>
  </Tab>
</Tabs>

### Use in app

To use the configured service in your app, add a configuration file similar to the following to your project.

<Tabs>
  <Tab title="Using default endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  source:
                    root: "/"

                  # PHP extensions.
                  runtime:
                    extensions:
                      - mongodb

                  [...]

                  # Relationships enable access from this app to a given service.
                  # The example below shows simplified configuration leveraging a default service
                  # (identified from the relationship name) and a default endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    mongodb:
              services:
                mongodb:
                  type: mongodb-enterprise:{{version:mongodb-enterprise:latest}}`
          }
    </DynamicCodeBlock>
  </Tab>

  <Tab title="Using explicit endpoints">
    <DynamicCodeBlock language="yaml" filename=".upsun/config.yaml">
      {`
              applications:
                # The name of the app container. Must be unique within a project.
                myapp:
                  # The location of the application's code.
                  source:
                    root: "/"

                  # PHP extensions.
                  runtime:
                    extensions:
                      - mongodb

                  [...]

                  # Relationships enable access from this app to a given service.
                  # The example below shows configuration with an explicitly set service name and endpoint.
                  # See the Application reference for all options for defining relationships and endpoints.
                  relationships:
                    mongodb:
                      service: mongodb
                      endpoint: mongodb
              services:
                mongodb:
                  type: mongodb-enterprise:{{version:mongodb-enterprise:latest}}`
          }
    </DynamicCodeBlock>
  </Tab>
</Tabs>

This configuration defines a single application (`myapp`), whose source code exists in the `<PROJECT_ROOT>/myapp` directory.<br />
`myapp` has access to the `mongodb` service, via a relationship whose name is [identical to the service name](#2-define-the-relationship)
(as per [default endpoint](/docs/configure-apps/image-properties/relationships) configuration for relationships).

From this, `myapp` can retrieve access credentials to the service through the [relationship environment variables](#relationship-reference).

```bash myapp/.environment theme={null}
# Set environment variables for individual credentials.
# For more information, please visit /docs/development/variables#service-environment-variables.
export DB_CONNECTION=="${MONGODB_SCHEME}"
export DB_USERNAME="${MONGODB_USERNAME}"
export DB_PASSWORD="${MONGODB_PASSWORD}"
export DB_HOST="${MONGODB_HOST}"
export DB_PORT="${MONGODB_PORT}"
export DB_DATABASE="${MONGODB_PATH}"

# Surface connection string variable for use in app.
export DATABASE_URL="${DB_CONNECTION}://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_DATABASE}"
```

The above file — `.environment` in the `myapp` directory — is automatically sourced by Upsun into the runtime environment, so that the variable `DATABASE_URL` can be used within the application to connect to the service.

Note that `DATABASE_URL`, and all Upsun [service environment variables](/docs/development/variables#service-environment-variables) like `MONGODB_HOST`, are environment-dependent.
Unlike the build produced for a given commit,
they can’t be reused across environments and only allow your app to connect to a single service instance on a single environment.

A file very similar to this is generated automatically for your when using the `upsun ify` command to [migrate a codebase to Upsun](/docs/get-started).

## Access the service directly

You can access MongoDB from you app container via [SSH](/docs/development/ssh).
Get the `host` from your [relationship](#relationship-reference).
Then run the following command:

```bash theme={null}
mongosh <MONGODB_HOST>
```

With the example value, that would be the following:

```bash theme={null}
mongosh mongodb.internal
```

You can obtain the complete list of available service environment variables in your app container by running `upsun ssh env`.

Note that the information about the relationship can change when an app is redeployed or restarted or the relationship is changed. So your apps should only rely on the [service environment variables](/docs/development/variables#service-environment-variables) directly rather than hard coding any values.

## Exporting data

The most straightforward way to export data from a MongoDB database is to open an SSH tunnel to it
and export the data directly using MongoDB's tools.

First, open an SSH tunnel with the Upsun CLI:

```bash theme={null}
upsun tunnel:open
```

That opens an SSH tunnel to all services on your current environment and produce output like the following:

```bash theme={null}
SSH tunnel opened on port 30000 to relationship: mongodb
```

The port may vary in your case.
You also need to obtain the user, password, and database name from the relationships array, as above.

Then, connect to that port locally using `mongodump` (or your favorite MongoDB tools) to export all data in that server:

```bash theme={null}
mongodump --port 30000 -u main -p main --authenticationDatabase main --db main
```

(If necessary, vary the `-u`, `-p`, `--authenticationDatabase` and `--db` flags.)

As with any other shell command it can be piped to another command to compress the output or redirect it to a specific file.

For further references, see the [official `mongodump` documentation](https://www.mongodb.com/docs/database-tools/mongodump/).

## Large databases

Upsun supports MongoDB databases of any size, including multi-terabyte deployments. The same service configuration applies whether your database holds gigabytes or tens of terabytes. Only the resources you allocate to it differ.

### Cloning at any size

When you create a [preview environment](/docs/environments), Upsun clones the entire parent environment (including its database) at the storage layer. The clone completes in seconds to under a minute regardless of database size. A 10 TB database clones in roughly the same time as a 10 GB one.

### What drives performance

Total disk size is rarely the limiting factor for query performance. What matters is the **active dataset** (or working set), the subset of documents, indexes, and pages your application actually reads and writes.

A 10 TB database that serves queries against 5 GB of hot data can outperform a 50 GB database. The smaller database performs worse if it scans entire collections on every request. As long as the active dataset fits in WiredTiger's internal cache, queries are served from memory without touching disk.

By contrast, queries that read most of a collection become more expensive as the collection grows. The same is true of indexes that effectively scan everything.

### Sizing for large datasets

Memory is the lever that keeps the active dataset hot. MongoDB containers use the [`HIGH_MEMORY` container profile](/docs/manage-resources/adjust-resources#advanced-container-profiles) by default. Combined with [Guaranteed CPU](/docs/manage-resources/guaranteed-resources), you can allocate up to **512 GB of RAM** to a single MongoDB container.

To work efficiently with a large database:

* Size memory to fit the active dataset in WiredTiger's cache.
* Make sure queries hit indexes, and avoid full collection scans on large collections.
* Watch index selectivity. An index that scans most of a large collection on each query loads gigabytes into memory, evicting the active dataset.
* Use [`explain()`](https://www.mongodb.com/docs/manual/reference/explain-results/) to verify which indexes a query uses and how many documents it examines.

Disk size alone, even into the multi-terabyte range, does not determine database performance. It determines what data you can store. Memory and query patterns determine how fast you can serve it.

## Upgrading

To upgrade to 6.0 from a version earlier than 5.0, you must successively upgrade major releases until you have upgraded to 5.0.
For example, if you are running a 4.2 image, you must upgrade first to 4.4 and then upgrade to 5.0 before you can upgrade to 6.0.

For more details on upgrading and how to handle potential application backward compatibility issues,
see the [MongoDB release notes](https://www.mongodb.com/docs/manual/release-notes/).

<Warning>
  Make sure you first test your migration on a separate branch.

  Also, be sure to take a backup of your production environment **before** you merge this change.
</Warning>

Downgrading isn't supported. If you want, for whatever reason, to downgrade you should create a mongodump, remove the service, recreate the service, and import your dump.
