DBCluster). Use these sizing recommendations to configure your volumes when deploying on Kubernetes by using the AlloyDB Omni Kubernetes operator.
When you create a DBCluster custom resource,
the AlloyDB Omni operator provisions Kubernetes PVCs based on the disks
that you define in the following fields:
- Primary and high availability (HA) standby instances: configured in the
spec.primarySpec.resources.disksfield on yourDBClustercustom resource. If you enable high availability by configuring thespec.availability.numberOfStandbysfield, each standby replica uses the same disk configuration as the primary instance. - Read pool instances: configured in
spec.resources.diskson eachDBInstancecustom resource where theinstanceTypeis set toReadPool. If you omit thespec.resourcessection on aDBInstanceresource, the read pool instance inherits the disk configuration from the parentDBClusterresource'sspec.primarySpec.resourcesfield.
Supported PVC volumes
The AlloyDB Omni operator doesn't provision all PVC volumes at the same time:
- Always provisioned: the operator always provisions
DataDisk,ObsDisk,BackupDisk, andLogDiskfor all primary, HA standby, and read pool database instance Pods. You must explicitly specifyDataDiskand its size in your manifest. SpecifyingObsDisk,BackupDisk, andLogDiskin your manifest is optional. If you omit them, as shown in the basic installation manifest, the operator still provisions these PVCs using their default sizes. - Not provisioned by default: the operator doesn't provision the
BackupRepoDiskvolume when you create a standaloneDBClusterresource or when you store backups in Cloud Storage or Amazon S3. It provisions the backup repository Pod and itsBackupRepoDiskPVC only when you create aBackupPlanresource to store backups locally on your Kubernetes cluster (that is, aBackupPlanresource without a remotebackupLocationfield).
The following table describes the persistent volumes that the AlloyDB Omni operator manages:
| Disk name | Mount path | Target Pod | Manifest configuration | Provisioning behavior | Purpose |
|---|---|---|---|---|---|
DataDisk |
/mnt/disks/pgsql |
Database Pod | Required | Always provisioned for each database Pod. | Stores the PostgreSQL database cluster directory
(PGDATA), tables, indexes, temporary files, and active
write-ahead log (WAL) segments. |
ObsDisk |
/obs |
Database Pod | Optional (default: 2Gi) |
Always provisioned for each database Pod. | Stores observability data, including PostgreSQL server logs
(postgresql.log), pgAudit logs
(postgresql.audit), internal logs
(postgresql.internal), and rotated .gz log
archives. |
BackupDisk |
/backup |
Database Pod | Optional (default: 10Gi) |
Always provisioned for each database Pod. | Provides a local staging directory for backup operations on the database Pod. |
LogDisk |
/archive |
Database Pod | Optional (default: 2Gi) |
Always provisioned for each database Pod. | Provides a dedicated WAL archive destination for custom or
third-party backup sidecars. If you don't use a custom WAL-archiving
sidecar, you can omit this disk from your manifest and leave it at its
default 2Gi size. |
BackupRepoDisk |
/backup |
Backup repository Pod | Optional (default: 10Gi) |
Not provisioned by default. Provisioned only when a
BackupPlan resource
stores backups locally
(not provisioned when no BackupPlan is configured or when
backups use Cloud Storage or Amazon S3). |
Provides a dedicated volume that stores physical database backups, incremental and differential backups, and archived WAL files when you use local storage backups. |
PVC sizing recommendations
Use the following guidelines to size each PVC volume based on your workload, logging configuration, and backup strategy.
DataDisk volume for primary database storage
The AlloyDB Omni operator always provisions the DataDisk volume for every
database Pod, and you must explicitly specify its size in your manifest. To
estimate the minimum capacity for DataDisk, use the following formula:
DataDisk capacity = (initial_dataset_size + projected_growth + max_wal_size) * 1.30
When you size the DataDisk volume, consider the following factors:
- Index overhead: PostgreSQL indexes and system catalog tables typically require an additional 20% to 50% of storage beyond raw table data.
- Active WAL headroom: high-throughput write transactions accumulate WAL
files in the
pg_waldirectory until checkpoints complete. Allocate enough storage to accommodate your configuredmax_wal_sizedatabase parameter (typically several gigabytes to tens of gigabytes, depending on your workload). To view or modify database parameters such asmax_wal_size, see Configure database parameters. - Temporary files and vacuum operations: query sorting, index creation, reindexing, and autovacuum operations require additional temporary disk space.
- General sizing rule: allocate 1.5 to 2 times your raw database size, including at least a 30% safety buffer.
ObsDisk volume for diagnostic and audit logs
The AlloyDB Omni operator always provisions the ObsDisk volume for every database
Pod (with the 2Gi default size if you omit it from your manifest). If
the ObsDisk volume fills up, PostgreSQL can't write new log entries, and log rotation
can stall. For information about how to configure log rotation and retention
settings for the ObsDisk volume, see
Configure log rotation.
When you size the ObsDisk volume, consider the following guidelines:
- Standard logging: a volume of 4 GiB to 10 GiB is sufficient for standard operational logging under the default log rotation settings (200 MB rotation threshold and 7-day retention).
- Audit logging (pgAudit): when you enable audit logging with pgAudit, audit logging generates significantly higher log volume. Allocate 20 GiB to 50 GiB or more, depending on your query rate and audit rule verbosity.
BackupRepoDisk volume for local backup repository
Unlike the database Pod disks, BackupRepoDisk isn't provisioned by default.
The AlloyDB Omni operator provisions the backup repository Pod and its
BackupRepoDisk PVC only when you create a
BackupPlan resource to store backups locally
on your Kubernetes cluster without a remote backupLocation field. If you omit
this disk from your DBCluster manifest, it uses the default size of 10Gi.
If you don't configure a BackupPlan resource, or if your BackupPlan resource
uses Cloud Storage with the GCS type or Amazon S3 with the S3 type, the
operator doesn't provision BackupRepoDisk. For more information about
configuring backup plans and resizing backup storage, see
Back up and restore in Kubernetes and
Resize a backup disk.
When you store backups locally, the BackupRepoDisk volume stores compressed
full, differential, and incremental backups along with archived WAL files. The
total storage required depends on your database size, daily data change rate,
the backup schedule defined in backupSchedules, and the retention period set by
backupRetainDays:
- Backup compression: compressed backups typically use 37% to 38% of the uncompressed database size, representing a 62% to 63% size reduction. For example, a 50 GiB database compresses to approximately 18.5 GiB.
- Backup schedule and retention: combining weekly full backups with daily incremental or differential backups requires significantly less storage than taking daily full backups.
The following table shows the benchmarked peak storage usage and recommended
BackupRepoDisk size (including a 20% buffer) across different backup
schedules for a 100 GiB database with a 10% daily data change rate and
the default 14-day retention period (backupRetainDays: 14):
Backup schedule (backupSchedules) |
Peak full backups | Differential backups | Incremental backups | Archived WAL files | Peak storage used | Recommended BackupRepoDisk size (+20% buffer) |
|---|---|---|---|---|---|---|
| Weekly full + daily incremental | 148.0 GiB | 0 GiB | 66.6 GiB | 155.4 GiB | 370.0 GiB | 444 GiB (~4.4x database size) |
| Weekly full + mid-week differential + daily incremental | 148.0 GiB | 22.2 GiB | 44.4 GiB | 155.4 GiB | 370.0 GiB | 444 GiB (~4.4x database size) |
| Weekly full + daily differential | 148.0 GiB | 155.4 GiB | 0 GiB | 155.4 GiB | 458.8 GiB | 551 GiB (~5.5x database size) |
| Daily full only (default schedule) | 592.0 GiB | 0 GiB | 0 GiB | 111.0 GiB | 703.0 GiB | 844 GiB (~8.4x database size) |
BackupDisk volume for database Pod backup staging
The AlloyDB Omni operator always provisions the BackupDisk volume for every
database Pod with a default size of 10 GiB (10Gi).
AlloyDB Omni uses the BackupDisk volume as a local staging directory
during backup operations. Because the default 10 GiB size is sufficient
for standard operations, you can omit BackupDisk from your DBCluster
manifest to use the default size.
LogDisk volume for custom WAL archiving
The AlloyDB Omni operator always provisions the LogDisk volume for every database
Pod with a default size of 2 GiB (2Gi). You only need to specify a
custom size for the LogDisk volume if you deploy a
custom or third-party sidecar container
that archives WAL files to the /archive directory. For standard
AlloyDB Omni operator deployments that use built-in backups, you can
omit LogDisk from your DBCluster manifest and leave it at its default
2Gi size.
Sizing reference by dataset size
The following table provides recommended PVC sizes for common raw dataset sizes:
| Raw data size | Recommended DataDisk size |
Recommended ObsDisk size |
Recommended BackupRepoDisk size (provisioned
for local backups only) |
Recommended BackupDisk size |
Recommended LogDisk size |
|---|---|---|---|---|---|
| 50 GiB | 100 GiB | 4 GiB (10 to 20 GiB with pgAudit) | 150 GiB | 10 GiB (default) | 2 GiB (default) |
| 200 GiB | 400 GiB | 10 GiB (20 to 50 GiB with pgAudit) | 600 GiB | 10 GiB (default) | 2 GiB (default) |
| 500 GiB | 1,000 GiB (1 TiB) | 15 GiB (30 to 60 GiB with pgAudit) | 1,500 GiB (1.5 TiB) | 10 GiB (default) | 2 GiB (default) |
| 1 TiB | 2,000 GiB (2 TiB) | 20 GiB (50 to 100 GiB with pgAudit) | 3,000 GiB (3 TiB) | 10 GiB (default) | 2 GiB (default) |
Monitor disk usage and I/O metrics
You can monitor live disk usage directly inside your database and backup
repository Pods by using kubectl or by collecting Prometheus metrics exported by
AlloyDB Omni.
Check disk usage by using kubectl
To check the current disk space usage of the mounted PVC volumes inside your database Pod and backup repository Pod, run the following commands:
Get the name of the database Pod for your
DBClusterresource:export DB_POD=$(kubectl get pod -n NAMESPACE -l alloydbomni.internal.dbadmin.goog/dbcluster=DB_CLUSTER_NAME,alloydbomni.internal.dbadmin.goog/task-type=database -o jsonpath='{.items[0].metadata.name}')Replace the following:
NAMESPACE: the Kubernetes namespace where your database cluster is deployed.DB_CLUSTER_NAME: the name of your database cluster.
Run
df -hinside the database container to view the capacity and usage of theDataDisk(/mnt/disks/pgsql),ObsDisk(/obs),BackupDisk(/backup), andLogDisk(/archive) volumes:kubectl exec -n NAMESPACE "${DB_POD}" -c database -- df -h /mnt/disks/pgsql /obs /backup /archiveIf you configured a
BackupPlanresource to store backups locally, get the name of the backup repository Pod and rundf -hto view the capacity and usage of theBackupRepoDiskvolume (/backup):export BACKUP_REPO_POD=$(kubectl get pod -n NAMESPACE -l alloydbomni.internal.dbadmin.goog/dbcluster=DB_CLUSTER_NAME,alloydbomni.internal.dbadmin.goog/backup-repository -o jsonpath='{.items[0].metadata.name}') kubectl exec -n NAMESPACE "${BACKUP_REPO_POD}" -c backuprepo -- df -h /backup
Monitor storage metrics by using Prometheus
AlloyDB Omni exports storage and disk I/O metrics on the
al-INSTANCE_ID-DB_CLUSTER_NAME-monitoring-system
service (port 9187). To learn how to scrape and query these metrics, see
Monitor AlloyDB Omni. For a
complete list of available metrics, see
AlloyDB Omni metrics.
Monitor the following disk metrics:
- Storage usage and capacity: Monitor the
alloydb_omni_node_storage_usage_per_disk_byteandalloydb_omni_node_storage_limit_per_disk_bytemetrics, which report the used storage and total capacity in bytes for each volume by using thedisklabel (for example,DataDisk,ObsDisk, orBackupDisk). Configure alerts when disk usage reaches 80% and 90% of capacity so that you can expand volumes before they run out of space. - Disk throughput and I/O operations: Monitor the
alloydb_omni_node_storage_read_bytes_count_totalandalloydb_omni_node_storage_write_bytes_count_totalmetrics for disk read and write throughput, and thealloydb_omni_node_storage_read_ops_count_totalandalloydb_omni_node_storage_write_ops_count_totalmetrics for read and write I/O operations.
Resize PVCs for an existing DBCluster
If you already created a DBCluster resource following
Create a database cluster, your
initial manifest likely specified only the DataDisk volume (for example, 10Gi), while
the AlloyDB Omni operator provisioned the ObsDisk (2Gi), BackupDisk
(10Gi), and LogDisk (2Gi) volumes with their default sizes. You can expand any
of these PVCs by updating your DBCluster manifest.
Before you resize a PVC, review the following requirements and limitations:
- StorageClass volume expansion: You can increase a disk's size only if
its Kubernetes
StorageClassresource setsallowVolumeExpansion: true. For more information, see Expanding Persistent Volumes Claims. - No shrinking or StorageClass changes: You can't decrease a disk's size,
and you can't change the
storageClassfield of an existing PVC after it is provisioned. - Resizing default-sized disks: To expand a disk that you previously
omitted from your manifest (such as the
ObsDiskvolume orBackupRepoDiskvolume), add an entry for that disk to thespec.primarySpec.resources.disksfield with asizefield larger than its current default capacity. Always keepDataDiskand any other existing disk entries in thediskslist when you update the manifest. - Pod restart behavior: When you modify the
resources.disksfield, the AlloyDB Omni operator updates the underlying PVC and restarts the database instance Pod to apply the new resource specification. Perform storage expansion during a planned maintenance window or configure high availability to minimize downtime.
To inspect and resize the PVCs for your DBCluster, follow these steps:
List the PVCs in your database cluster's namespace to check their current capacities and
StorageClassresource:kubectl get pvc -n NAMESPACEReplace
NAMESPACEwith the namespace where you deployed yourDBCluster(for example,default).The output is similar to the following for a cluster named
my-db-cluster:NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE backupdisk-al-1060-my-db-cluster-0 Bound pvc-45a28be2-a111-40ed-9641-61b9d25f313b 10Gi RWO standard-rwo 10m datadisk-al-1060-my-db-cluster-0 Bound pvc-c23a1ab8-f97c-4449-9072-502b6d9ba869 10Gi RWO standard-rwo 10m logdisk-al-1060-my-db-cluster-0 Bound pvc-f0c41d15-bb13-4d28-b94b-01a28dc67ef6 2Gi RWO standard-rwo 10m obsdisk-al-1060-my-db-cluster-0 Bound pvc-69ea1ca7-a868-4dc9-a9f8-503d5e5f2387 2Gi RWO standard-rwo 10mVerify that the
StorageClassresource used by your PVCs supports volume expansion:kubectl get storageclass STORAGE_CLASS_NAME -o jsonpath='{.allowVolumeExpansion}{"\n"}'Replace
STORAGE_CLASS_NAMEwith the storage class name from theSTORAGECLASScolumn of the previous output (for example,standard-rwo). Confirm that the command returnstrue.Update the
spec.primarySpec.resources.disksfield in yourDBClustermanifest to increase thesizevalue of theDataDiskvolume and add any default-sized disks that you need to expand (such as theObsDiskvolume orBackupRepoDiskvolume).The following example manifest expands the
DataDiskvolume to400Gi, expands theObsDiskvolume from its2Gidefault to10Gi, and configures theBackupRepoDiskvolume at600Gifor a 200 GiB workload:apiVersion: alloydbomni.dbadmin.goog/v1 kind: DBCluster metadata: name: DB_CLUSTER_NAME namespace: NAMESPACE spec: databaseVersion: "18.3.0" primarySpec: adminUser: passwordRef: name: db-pw-DB_CLUSTER_NAME resources: cpu: 4 memory: 32Gi disks: - name: DataDisk size: 400Gi storageClass: STORAGE_CLASS_NAME - name: ObsDisk size: 10Gi storageClass: STORAGE_CLASS_NAME - name: BackupRepoDisk size: 600Gi storageClass: STORAGE_CLASS_NAMEReplace the following:
DB_CLUSTER_NAME: the name of your database cluster—for example,my-db-cluster.NAMESPACE: the namespace of your database cluster.STORAGE_CLASS_NAME: the name of the KubernetesStorageClassresource used by your persistent volumes—for example,standard-rwo. If you omitted thestorageClassfield when you created the cluster, you can continue to omit it so that the operator uses your cluster's defaultStorageClass.
Apply the updated
DBClustermanifest:kubectl apply -f DB_CLUSTER_MANIFEST.yamlReplace
DB_CLUSTER_MANIFESTwith the path to yourDBClustermanifest file.Verify that the PVCs and
DBClusterstatus reflect the expanded sizes:kubectl get pvc -n NAMESPACEYou can also inspect the
allocatedResources.disksstatus field on theDBClusterresource:kubectl get dbcluster DB_CLUSTER_NAME -n NAMESPACE -o jsonpath='{.status.primary.allocatedResources.disks}{"\n"}'Replace the following:
NAMESPACE: the namespace of your database cluster.DB_CLUSTER_NAME: the name of your database cluster.
For more information about resizing compute and storage resources, see Resize your Kubernetes-based database cluster.
What's next
- Install AlloyDB Omni using the container orchestrator
- Manage and monitor AlloyDB Omni
- Configure log rotation
- Back up and restore in Kubernetes
- Manage high availability in Kubernetes
- Create a read pool instance in Kubernetes