---
schema_version: "1"
id: 63f2b623e42184ccf0d710a46367322c88578ef957487f267173c325abaeb7ab
title: Configuring Persistence Gateway with Runtime Fabric
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/runtime-fabric/2.11/persistence-gateway.md
canonical_url: https://docs.mulesoft.com/runtime-fabric/2.11/persistence-gateway
source_site: docs.mulesoft.com
content_type: documentation
content_hash: 4a084cc0adaf06b05d592b42e1128b22c771b6dca6886910da2db14da20d4179
description: MuleSoft Documentation Site
release: "2.11"
latest: false
---
---
product: Runtime Fabric
version: 2.11
---

# Configuring Persistence Gateway with Runtime Fabric

> For the full documentation index, see: https://docs.mulesoft.com/llms.txt

Anypoint Runtime Fabric provides Persistence Gateway, which enables Mule applications deployed to a
Mule runtime instance to store and share data across application replicas and restarts.

> [!NOTE] You can also use the Mule Maven plugin version 3.5.4 or later to enable persistent object
> stores for Runtime Fabric deployments.

## Using Persistence Gateway in a Mule Application

After Persistence Gateway is configured in Anypoint Runtime Fabric, it is available for Mule
applications deployed to Mule runtime engine, version 4.2.1 or later. When configured, users can
select **Use Persistent Object Storage** when deploying an application using Runtime Manager. See
[Deploy a Mule Application to Runtime Fabric](https://docs.mulesoft.com/runtime-fabric/2.11/deploy-to-runtime-fabric) for more information.

Mule applications use the Object Store v2 REST API via the Object Store Connector to connect to
Persistence Gateway. This enables you to deploy to both Anypoint Runtime Fabric and CloudHub without
having to modify your Mule application.

> [!NOTE] After deleting an application, persistent data may not be deleted immediately. Runtime
> Fabric cleans persistence data every 60 minutes.

## Persistent Gateway Limits

The following table lists the limits on the data stored by Persistence Gateway:

<table><colgroup><col> <col></colgroup><thead><tr><th>Limit</th><th>Description</th></tr></thead><tbody><tr><td><div><div><p>Maximum TTL.</p></div></div></td><td><div><div><p>The amount of time data is stored in Persistence Gateway, value is set to 30 days.</p></div></div></td></tr></tbody></table>

## Before You Begin

Before enabling Persistence Gateway, ensure that you have:

- Created a PostgreSQL database to serve as the data source for data stored by Persistence Gateway.
  This database must be compatible with a
  [supported version of PostgreSQL](https://www.postgresql.org/support/versioning/) that does not
  reserve the `partition` keyword.

- Granted the PostgreSQL user CREATE, INSERT, SELECT, UPDATE, and DELETE privileges.

> [!NOTE] Only plain text connections to the database are supported.

## Configure Persistence Gateway

During configuration, Persistence Gateway creates the required database schema. Afterwards, when an
application deployed to Runtime Fabric is configured to use persistent object storage, the
Persistence Gateway writes the necessary rows to the database.

To configure Persistence Gateway, you must create a Kubernetes custom resource that allows the
cluster to connect to your persistence data store.

1.  Create a Kubernetes secret:

    kubectl create secret generic <SECRET NAME> -n rtf
    --from-literal=persistence-gateway-creds='postgres://username:pass@host:port/databasename'

    > [!IMPORTANT]
    >
    > - Do not change `--from-literal=persistence-gateway-creds`. You can replace `<SECRET NAME>`
    >   with any value you want to use for the secret.
    >
    > - Do not use the "@" character in the database username.
    >
    > - If your PostgresSQL user account password contains special characters, make sure to encode
    >   your connection URL before pushing it as Kubernetes secret.

2.  Create a custom resource for your data store:

    1.  Copy the custom resource template from
        [Kubernetes Custom Resource Template](#k8-custom-resource-template) to a file called
        `custom-resource.yaml`.

    2.  Ensure the value of `secretRef: name` matches the `name` field defined in your Kubernetes
        secret file.

    3.  Modify other fields of the custom resource template as required for your environment.

    4.  Run `kubectl apply -f custom-resource.yaml`.

3.  Check the logs of the Persistence Gateway pod to ensure it can communicate with the database:

    ```copy
    kubectl get pods -n rtf
    ```

    Look for pods with the name prefix `persistence-gateway`

    ```copy
    kubectl logs -f persistence-gateway-6dfb98949c-7xns9 -n rtf
    ```

    The output of this command should be similar to this:

    2021/04/09 16:35:31 Connecting to PostgreSQL backend... 2021/04/09 16:35:32 Starting watcher for
    /var/run/secrets/rtf-object-store/persistence-gateway-creds 2021/04/09 16:35:32 Watching for
    changes on /var/run/secrets/rtf-object-store/persistence-gateway-creds 2021/04/09 16:35:35
    Successfully connected to the PostgreSQL backend. 192.168.2.101 - - \[09/Apr/2021:16:35:55
    +0000\] "GET /api/v1/status/ready HTTP/1.1" 200 2 "" "kube-probe/1.18+"

## Persistence Gateway with Authorized Namespaces

If you use [authorized namespace](https://docs.mulesoft.com/runtime-fabric/2.11/install-helm#optional-configure-authorized-namespaces) and want to
use persistence gateway, edit the RoleBinding by adding a new `rtf-persistence-gateway` subject:

```copy
subjects:
  - kind: ServiceAccount
    name: rtf-persistence-gateway
    namespace: <rtf_namespace>
```

## Kubernetes Custom Resource Template

Use the example template below to create a Kubernetes custom resource. This custom resource enables
the Kubernetes cluster to connect to your data store.

```yaml
apiVersion: rtf.mulesoft.com/v1
kind: PersistenceGateway
metadata:
  name: default
  namespace: rtf
spec:
  objectStore:
    backendDriver: postgresql
    maxBackendConnectionPool: 20
    replicas: 2
    secretRef:
      name: persistence-gateway-creds
    resources:
      limits:
        cpu: 250m
        memory: 250Mi
      requests:
        cpu: 200m
        memory: 75Mi
    topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: topology.kubernetes.io/zone
        whenUnsatisfiable: ScheduleAnyway
```

Modify these fields based on your environment:

<table><colgroup><col> <col> <col></colgroup><thead><tr><th>Field</th><th>Description</th><th>Default Value</th></tr></thead><tbody><tr><td><div><div><p><code>kind</code></p></div></div></td><td><div><div><p>The type of custom resource. The only supported value is <code>PersistenceGateway</code>.</p></div></div></td><td><div><div><p>PersistenceGateway</p></div></div></td></tr><tr><td><div><div><p><code>metadata.name</code></p></div></div></td><td><div><div><p>The internal identifier for this custom resource. The value for this field should be <code>default</code>.</p></div></div></td><td><div><div><p>default</p></div></div></td></tr><tr><td><div><div><p><code>metadata.namespace</code></p></div></div></td><td><div><div><p>The namespace where the secret is applied. The supported value is <code>rtf</code>.</p></div></div></td><td><div><div><p>rtf</p></div></div></td></tr><tr><td><div><div><p><code>spec.objectStore.backendDriver</code></p></div></div></td><td><div><div><p>The driver used by the data store. Only <code>postgresql</code> is supported.</p></div></div></td><td><div><div><p>postgresql</p></div></div></td></tr><tr><td><div><div><p><code>spec.objectStore.maxBackendConnectionPool</code></p></div></div></td><td><div><div><p>The maximum number of simultaneous open connections to the data store.</p></div></div></td><td><div><div><p>20</p></div></div></td></tr><tr><td><div><div><p><code>spec.objectStore.replicas</code></p></div></div></td><td><div><div><p>The number of replicas of Persistence Gateway.</p></div></div></td><td><div><div><p>2</p></div></div></td></tr><tr><td><div><div><p><code>spec.objectStore.resources.limits.cpu</code></p></div></div></td><td><div><div><p>The CPU resource limits for the Persistence Gateway pods.</p></div></div></td><td><div><div><p>250m</p></div></div></td></tr><tr><td><div><div><p><code>spec.objectStore.resources.limits.memory</code></p></div></div></td><td><div><div><p>The memory resource limits for the Persistence Gateway pods.</p></div></div></td><td><div><div><p>150Mi</p></div></div></td></tr><tr><td><div><div><p><code>spec.objectStore.resources.requests.cpu</code></p></div></div></td><td><div><div><p>The CPU resource requests for the Persistence Gateway pods.</p></div></div></td><td><div><div><p>200m</p></div></div></td></tr><tr><td><div><div><p><code>spec.objectStore.resources.requests.memory</code></p></div></div></td><td><div><div><p>The memory resource requests for the Persistence Gateway pods.</p></div></div></td><td><div><div><p>75Mi</p></div></div></td></tr><tr><td><div><div><p><code>spec.objectStore.secretRef.name</code></p></div></div></td><td><div><div><p>The name of the Persistence Gateway credentials defined in the Kubernetes secret file.</p></div></div></td><td><div><div><p>persistence-gateway-creds</p></div></div></td></tr><tr><td><div><div><p><code>spec.objectStore.topologySpreadConstraints.maxSkew</code></p></div></div></td><td><div><div><p>Describes the degree to which pods may be unevenly distributed.</p></div></div></td><td><div><div><p>1</p></div></div></td></tr><tr><td><div><div><p><code>spec.objectStore.topologySpreadConstraints.topologyKey</code></p></div></div></td><td><div><div><p>Key that understands which criteria to use to distribute pods.</p></div></div></td><td><div><div><p>topology.kubernetes.io/zone</p></div></div></td></tr><tr><td><div><div><p><code>spec.objectStore.topologySpreadConstraints.whenUnsatisfiable</code></p></div></div></td><td><div><div><p>Indicates how to deal with a pod if it doesn’t satisfy the spread constraint.</p></div></div></td><td><div><div><p>ScheduleAnyway</p></div></div></td></tr></tbody></table>

> [!NOTE] The default CPU, memory, and limit values are based on a small number of deployed Mule
> applications. Modify these values based on the requirements of your environment.

## Persistence Gateway Application Data

Persistence Gateway stores application data using these two tables:

```copy
CREATE TABLE IF NOT EXISTS stores (
	id SERIAL PRIMARY KEY,
	name VARCHAR(255) NOT NULL,
	org_id VARCHAR(255) NOT NULL,
	env_id VARCHAR(255) NOT NULL,
	default_ttl_seconds int NOT NULL,
	is_fixed_ttl bool NOT NULL,
	CONSTRAINT UK_stores UNIQUE (name, org_id, env_id)
);
CREATE TABLE IF NOT EXISTS items (
	store_id INT NOT NULL REFERENCES stores(id),
	key VARCHAR(255) NOT NULL,
	partition VARCHAR(255) NOT NULL,
	value_type VARCHAR(10) NOT NULL,
	number_value integer,
	string_value text,
	binary_value bytea,
	last_updated timestamp,
	is_fixed_ttl bool NOT NULL,
	ttl timestamp NOT NULL,
	CONSTRAINT UK_items UNIQUE (key, store_id, partition)
);
	CREATE INDEX IF NOT EXISTS IDX_items_ttl ON items(ttl)
;
```

To migrate the persistent data from one cluster to another, backup these two tables entirely from
the source cluster and recreate them on the target one database. Do not to have applications
deployed during this process on both clusters to prevent unexpected results.

If you’re using a version of the Runtime Fabric agent higher than 2.6.22, the `id` parameter in the
`CREATE TABLE IF NOT EXISTS items` statement no longer applies. For previous versions of the Runtime
Fabric agent 2.6.22, the `id` parameter is available in the items table.

## See Also

- [Deploy a Mule Application to Runtime Fabric](https://docs.mulesoft.com/runtime-fabric/2.11/deploy-to-runtime-fabric)

- [Deploy Applications to Runtime Fabric Using the Mule Maven Plugin](https://docs.mulesoft.com/mule-runtime/latest/deploy-to-rtf)
