> For the complete documentation index, see [llms.txt](https://docs.carto.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.carto.com/carto-self-hosted/best-practices/operations/operations-best-practices.md).

# Operations best practices

## Overview

Follow these best practices for ongoing CARTO Self-Hosted operations.

## Manage configuration as code

Treat your [configuration](/carto-self-hosted/concepts/configuration-management.md) as a tracked, reviewable artifact — not ad-hoc edits against a live deployment. The specifics differ by deployment method, but the principles are the same.

**For Helm deployments:**

* **Keep `customizations.yaml` in version control (Git).** It is the single file you own and the source of truth for your deployment. Commit every change so you have history, blame, and the ability to roll back.
* **Never edit configuration directly against the cluster.** Change the file, review it, then apply with `helm upgrade`. This keeps what's deployed and what's in Git in sync.
* **Review changes before applying.** Use pull requests for config changes, and run the [preflight checks](/carto-self-hosted/deployment/kubernetes-helm.md) before `helm upgrade` so a bad value is caught before it reaches production.
* **Store `carto-values.yaml` and `carto-secrets.yaml` alongside it**, but see secrets handling below — `carto-secrets.yaml` must never be committed in plaintext.

**For Kots deployments:**

* **Manage configuration through the Admin Console**, not by hand. The Config tab is the source of truth, and **Version history** is your change log — every Save config + Deploy creates a version you can diff and redeploy.
* **Back up the configuration for disaster recovery** instead of keeping a parallel copy by hand. Follow CARTO's [Kots backup procedure](/carto-self-hosted/operations/backup-and-restore/backups.md#backup-configuration-kots), and for full DR best practices — snapshots that include the Admin Console, an out-of-cluster storage destination, and scheduled retention — follow Replicated's [backup and restore with snapshots](https://docs.replicated.com/vendor/snapshots-overview).
* **Only change the Custom Configuration field with CARTO Support guidance.**

### Secrets handling

Your license and credentials must never live in plaintext in version control.

* **Do not commit `carto-secrets.yaml`** (or any secret values) to Git. Store them in a secrets manager — HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager — or encrypt them at rest with SOPS or Sealed Secrets.
* **Reference Kubernetes Secrets instead of inlining values.** In `customizations.yaml`, prefer `existingSecret` references (as in the database and bucket examples) over embedding passwords directly.
* **Rotate credentials deliberately.** See [Rotating keys](/carto-self-hosted/operations/upgrades/rotating-keys.md).

### Configuration across upgrades

When you move to a new release, CARTO replaces `carto-values.yaml` (Helm) or the underlying chart (Kots). You only own your overrides — `customizations.yaml` for Helm, or the Admin Console config for Kots — so your settings carry forward. After any upgrade, re-review your configuration against the new release notes in case defaults or available options changed.

## Update cadence

CARTO releases updates regularly with new features, bug fixes, and security patches. To stay supported and secure:

* **Check release notes monthly** — review the [CARTO Self-Hosted release notes](/carto-self-hosted/release-notes.md) for new versions
* **Stay within 2 minor versions of the latest release** — older versions may not receive security backports
* **Test updates in a development environment first** before applying to production
* **Schedule maintenance windows** for upgrades to minimize user disruption

For Helm deployments, update by running `helm upgrade` with the new chart version. For Kots deployments, use the Version History tab in the Admin Console.

## Backup strategy

**What to back up:**

| Item                         | Backup method                                                    | Frequency       | Retention       |
| ---------------------------- | ---------------------------------------------------------------- | --------------- | --------------- |
| PostgreSQL metadata database | Cloud provider automated snapshot                                | Daily           | 30 days minimum |
| `customizations.yaml`        | Version control (Git)                                            | On every change | Indefinitely    |
| `carto-secrets.yaml`         | Secrets manager (Vault, AWS Secrets Manager, GCP Secret Manager) | On every change | Indefinitely    |

{% hint style="warning" %}
The PostgreSQL database is the most critical component to back up. A lost metadata database means losing all maps, workflows, connections, and user data. Test your restore procedure at least quarterly.
{% endhint %}

**Object storage:** Import/Temp bucket files are ephemeral and do not need to be backed up. Assets/Thumbnails bucket files should be included in backups as they cannot be regenerated on demand. *(Kots: Temp Bucket / Assets Bucket — Helm: Import Bucket / Thumbnails Bucket)*

## Monitoring and alerting

Configure alerts for the following conditions:

| Alert                      | Threshold                  | Action                                              |
| -------------------------- | -------------------------- | --------------------------------------------------- |
| Pod restart count          | > 2 restarts in 10 minutes | Investigate `kubectl logs` for the affected pod     |
| PostgreSQL CPU utilization | > 80% sustained            | Tune connection pool or scale the database instance |
| PostgreSQL storage         | > 80% used                 | Scale storage or enable auto-grow                   |
| Valkey memory utilization  | > 85% of `maxmemory`       | Increase Valkey memory or review cache policy       |
| API error rate             | > 1% of requests           | Check `maps-api` and `workspace-api` logs           |
| Node disk usage            | > 80%                      | Clean up unused images or expand disk               |

CARTO services emit structured logs to **stdout/stderr** and run as standard Kubernetes workloads, but CARTO does **not** include a bundled monitoring stack — collecting these logs and metrics and configuring alerting at the infrastructure level is your responsibility. Use your cloud provider's native monitoring (Cloud Monitoring, CloudWatch, Azure Monitor) or a third-party observability stack (Datadog, Prometheus + Grafana) to collect and route these alerts. See [Monitoring & Observability](/carto-self-hosted/operations/troubleshooting/monitoring.md) for the full guidance.

## Disaster recovery

Plan for the following failure scenarios:

**Database failure:** With a managed PostgreSQL service (Multi-AZ or high-availability configuration), failover is automatic. Ensure your CARTO configuration points to the database endpoint or connection string (not a specific IP) so it follows automatic failover.

**Cluster failure (Kubernetes — Helm or Kots):** If using Helm, your full deployment configuration is in version-controlled YAML files (`customizations.yaml`, `carto-values.yaml`, `carto-secrets.yaml`). Recovery involves provisioning a new cluster and running `helm install`. Target a Recovery Time Objective (RTO) based on your cluster provisioning time.

**VM failure (Single VM — embedded cluster):** The entire CARTO stack runs on one machine. If the VM fails, recovery involves:

1. Provision a new VM of the same size
2. Re-run the CARTO embedded cluster installer
3. Restore the database from your latest snapshot
4. Re-upload the license and re-apply your configuration in the Admin Console

Keep your license file and a record of all Admin Console settings (domain, database credentials, storage credentials) in a secure location so recovery does not require contacting support.

**Full disaster recovery test:** Run a full DR test at least twice a year:

{% hint style="warning" %}
Do not use your production license directly for DR tests. Contact [CARTO Support](https://support.carto.com) before running a full recovery test, as the existing license must be freed before it can be applied to a new instance.
{% endhint %}

{% tabs %}
{% tab title="Kubernetes" %}

1. Create a new cluster in a different region or zone
2. Restore the database from the most recent snapshot
3. Apply your Helm/Kots configuration and deploy CARTO
4. Verify the application is functional
   {% endtab %}

{% tab title="Single VM" %}

1. Provision a new VM in a different zone
2. Run the embedded cluster installer
3. Restore the database from the most recent snapshot
4. Re-apply the configuration in the Admin Console
5. Verify the application is functional
   {% endtab %}
   {% endtabs %}

## Capacity review

Review resource utilization quarterly:

* Check CPU and memory usage across CARTO pods — scale before hitting 80% sustained utilization
* Review PostgreSQL storage growth rate — project when you will need to expand


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.carto.com/carto-self-hosted/best-practices/operations/operations-best-practices.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
