Extensions Cache

StackGres can cache PostgreSQL extensions locally to speed up cluster deployments and reduce external network dependencies.

Note: The extensions cache is an experimental feature.

Overview

Without caching, each cluster pod downloads extensions from the repository when starting. The extensions cache stores downloaded extensions locally, providing:

  • Faster deployments: No need to download from external repository
  • Reduced bandwidth: Download once, use many times
  • Offline capability: Deploy clusters without internet access (with pre-loaded cache)
  • Consistency: All clusters use the same cached extension binaries

Enabling the Cache

Via SGConfig

Configure the cache in the SGConfig resource:

apiVersion: stackgres.io/v1
kind: SGConfig
metadata:
  name: stackgres-config
  namespace: stackgres
spec:
  extensions:
    cache:
      enabled: true
      persistentVolume:
        size: 10Gi
        storageClass: fast-storage

Via Helm Values

Enable during operator installation:

# values.yaml
extensions:
  cache:
    enabled: true
    persistentVolume:
      size: 10Gi
helm install stackgres-operator stackgres-charts/stackgres-operator \
  -f values.yaml

Cache Configuration Options

Persistent Volume

Use a PersistentVolumeClaim for cache storage:

spec:
  extensions:
    cache:
      enabled: true
      persistentVolume:
        size: 20Gi
        storageClass: standard

For testing only, use a host path:

spec:
  extensions:
    cache:
      enabled: true
      hostPath: /var/cache/stackgres/extensions

Warning: Host path is not suitable for production as it doesn’t survive node failures.

Pre-Loading Extensions

Pre-load commonly used extensions into the cache:

spec:
  extensions:
    cache:
      enabled: true
      preLoadedExtensions:
        - postgis
        - pgvector
        - timescaledb
      persistentVolume:
        size: 20Gi

Pre-Load Patterns

Use patterns to pre-load multiple extensions:

preLoadedExtensions:
  - postgis           # Specific extension
  - pg*               # All extensions starting with 'pg'
  - "*vector*"        # All extensions containing 'vector'

How It Works

  1. First Request: When a cluster needs an extension:

    • Cache checks if extension is available locally
    • If not, downloads from repository and stores in cache
    • Extension is provided to the cluster
  2. Subsequent Requests: For the same extension:

    • Cache serves extension directly from local storage
    • No external network request needed
  3. Cache Invalidation: Extensions are cached by version

    • Different versions are cached separately
    • Updating extension version downloads new version

Monitoring the Cache

Check Cache Status

# View cache pod
kubectl get pods -n stackgres -l app=stackgres-extensions-cache

# Check cache PVC
kubectl get pvc -n stackgres | grep extensions-cache

# View cache logs
kubectl logs -n stackgres -l app=stackgres-extensions-cache

Cache Size

Monitor cache disk usage:

kubectl exec -n stackgres -l app=stackgres-extensions-cache -- \
  du -sh /var/cache/extensions

Offline Deployments

For air-gapped environments:

Step 1: Pre-Load Cache Online

On a connected environment:

spec:
  extensions:
    cache:
      enabled: true
      preLoadedExtensions:
        - postgis
        - pgvector
        - timescaledb
        - pg_stat_statements
      persistentVolume:
        size: 30Gi

Step 2: Export Cache

Export the cache volume contents:

kubectl cp stackgres/extensions-cache-pod:/var/cache/extensions ./extensions-backup

Step 3: Import to Air-Gapped Environment

Import the cache to the isolated environment:

kubectl cp ./extensions-backup stackgres/extensions-cache-pod:/var/cache/extensions

Cache with Custom Repository

When using a custom extensions repository:

spec:
  extensions:
    repositoryUrls:
      - https://my-company.example.com/extensions/repository
    cache:
      enabled: true
      persistentVolume:
        size: 10Gi

The cache works with any configured repository.

Best Practices

  1. Size appropriately: Estimate cache size based on extensions used

    • PostGIS: ~500MB
    • TimescaleDB: ~300MB
    • Most extensions: 10-50MB
  2. Use persistent storage: Always use PersistentVolume for production

  3. Pre-load common extensions: Reduce initial deployment time

  4. Monitor disk usage: Set up alerts for cache volume capacity

  5. Use fast storage: SSD-backed storage improves performance

Extensions Metadata Refresh

Note: This setting controls the cached extensions metadata, not the on-cluster extensions binary cache described above.

Separately from the binary cache, StackGres periodically polls the extensions repository to refresh the extensions metadata (the catalog of available extensions and versions). The refresh frequency is configurable under spec.extensions in the SGConfig resource:

spec:
  extensions:
    refreshInterval: P7D
    refreshEnabled: true
  • refreshInterval (string, default P7D): how often the cached extensions metadata is refreshed from the extensions repository, expressed as an ISO-8601 duration (for example P7D for 7 days or PT1H for 1 hour). The default is 1 week. Any configured value is clamped up to a minimum of 1 hour, so values below 1 hour are treated as 1 hour.
  • refreshEnabled (boolean, default true): when set to false, the extensions metadata is fetched once and never refreshed afterwards.

Disabling the refresh, or using a long interval, reduces the number of outbound requests StackGres makes to the extensions repository. This is useful in air-gapped or rate-limited environments where polling the repository is undesirable.