name: pg_local_cache_benchmark

services:
  pg-local-cache:
    build:
      context: ..
      dockerfile: Dockerfile
      args:
        POSTGRES_IMAGE: ${PGLC_BENCH_POSTGRES_IMAGE:-postgres:16.14-bookworm}
    image: ${PGLC_BENCH_PGLC_IMAGE:?PGLC_BENCH_PGLC_IMAGE is required}
    restart: "no"
    cpus: "${PGLC_BENCH_SERVER_CPUS:-4.0}"
    mem_limit: ${PGLC_BENCH_SERVER_MEMORY:-2g}
    shm_size: 1gb
    environment:
      POSTGRES_DB: benchmark
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
      PG_LOCAL_CACHE_DATABASE: benchmark
      PG_LOCAL_CACHE_ROLE: local_cache_benchmark_worker
      PG_LOCAL_CACHE_BIND_ADDRESS: 0.0.0.0
      PG_LOCAL_CACHE_PORT: "6380"
      PG_LOCAL_CACHE_WORKERS: "${PGLC_BENCH_PG_LOCAL_CACHE_WORKERS:-4}"
      PG_LOCAL_CACHE_CACHE_ENTRIES: "${PGLC_BENCH_CACHE_ENTRIES:-65536}"
      PG_LOCAL_CACHE_RELATION_STATES: "1024"
      PG_LOCAL_CACHE_MAX_CLIENTS: "${PGLC_BENCH_MAX_CLIENTS:-64}"
      PG_LOCAL_CACHE_MAX_CLIENTS_PER_WORKER: "64"
      PG_LOCAL_CACHE_MEMORY_BUDGET_MB: "768"
      PG_LOCAL_CACHE_MAX_WORKER_PROCESSES: "34"
      PG_LOCAL_CACHE_IDLE_TIMEOUT_MS: "300000"
      PG_LOCAL_CACHE_STATEMENT_TIMEOUT_MS: "2000"
      PG_LOCAL_CACHE_LOCK_TIMEOUT_MS: "250"
      PG_LOCAL_CACHE_SINGLEFLIGHT_WAIT_MS: "${PGLC_BENCH_SINGLEFLIGHT_WAIT_MS:-25}"
      PG_LOCAL_CACHE_MAX_PIPELINE_COMMANDS: "256"
      PG_LOCAL_CACHE_MAX_DIRTY_KEYS: "4096"
      PG_LOCAL_CACHE_AUTH_TOKEN_FILE: /run/secrets/pg_local_cache_auth_token
    secrets:
      - source: postgres_password
        target: postgres_password
        mode: 0600
      - source: pg_local_cache_auth_token
        target: pg_local_cache_auth_token
        mode: 0600
    command:
      - postgres
      - -c
      - max_connections=300
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ulimits:
      nofile:
        soft: 65536
        hard: 65536
    healthcheck:
      test: ["CMD", "/usr/local/bin/pg_local_cache_healthcheck"]
      interval: 2s
      timeout: 5s
      start_period: 60s
      retries: 30
    networks:
      - benchmark

  postgres-plain:
    image: ${PGLC_BENCH_POSTGRES_IMAGE:-postgres:16.14-bookworm}
    restart: "no"
    cpus: "${PGLC_BENCH_SERVER_CPUS:-4.0}"
    mem_limit: ${PGLC_BENCH_SERVER_MEMORY:-2g}
    shm_size: 1gb
    environment:
      POSTGRES_DB: benchmark
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
    command:
      - postgres
      - -c
      - max_connections=300
    secrets:
      - source: postgres_password
        target: postgres_password
        mode: 0600
    volumes:
      - plain_postgres_data:/var/lib/postgresql/data
    ulimits:
      nofile:
        soft: 65536
        hard: 65536
    healthcheck:
      test:
        - CMD-SHELL
        - pg_isready --username postgres --dbname benchmark
      interval: 2s
      timeout: 3s
      start_period: 30s
      retries: 30
    networks:
      - benchmark

  valkey:
    image: ${PGLC_BENCH_VALKEY_IMAGE:-valkey/valkey:9.1.1-trixie}
    restart: "no"
    cpus: "${PGLC_BENCH_SERVER_CPUS:-4.0}"
    mem_limit: ${PGLC_BENCH_SERVER_MEMORY:-2g}
    command:
      - valkey-server
      - --save
      - ""
      - --appendonly
      - "no"
      - --protected-mode
      - "no"
      - --requirepass
      - ${PGLC_BENCH_AUTH_TOKEN:?PGLC_BENCH_AUTH_TOKEN is required}
      - --loglevel
      - warning
    ulimits:
      nofile:
        soft: 65536
        hard: 65536
    healthcheck:
      test:
        - CMD
        - valkey-cli
        - --no-auth-warning
        - -a
        - ${PGLC_BENCH_AUTH_TOKEN:?PGLC_BENCH_AUTH_TOKEN is required}
        - PING
      interval: 2s
      timeout: 3s
      retries: 30
    networks:
      - benchmark

  redis:
    image: ${PGLC_BENCH_REDIS_IMAGE:-redis:8.8.1-trixie}
    restart: "no"
    cpus: "${PGLC_BENCH_SERVER_CPUS:-4.0}"
    mem_limit: ${PGLC_BENCH_SERVER_MEMORY:-2g}
    command:
      - redis-server
      - --save
      - ""
      - --appendonly
      - "no"
      - --protected-mode
      - "no"
      - --requirepass
      - ${PGLC_BENCH_AUTH_TOKEN:?PGLC_BENCH_AUTH_TOKEN is required}
      - --loglevel
      - warning
    ulimits:
      nofile:
        soft: 65536
        hard: 65536
    healthcheck:
      test:
        - CMD
        - redis-cli
        - --no-auth-warning
        - -a
        - ${PGLC_BENCH_AUTH_TOKEN:?PGLC_BENCH_AUTH_TOKEN is required}
        - PING
      interval: 2s
      timeout: 3s
      retries: 30
    networks:
      - benchmark

  benchmark:
    profiles: ["runner"]
    build:
      context: ..
      dockerfile: benchmarks/Dockerfile
      args:
        POSTGRES_IMAGE: ${PGLC_BENCH_POSTGRES_IMAGE:-postgres:16.14-bookworm}
    image: ${PGLC_BENCH_RUNNER_IMAGE:?PGLC_BENCH_RUNNER_IMAGE is required}
    restart: "no"
    user: "${PGLC_BENCH_UID:-1000}:${PGLC_BENCH_GID:-1000}"
    cpus: "${PGLC_BENCH_CLIENT_CPUS:-4.0}"
    mem_limit: ${PGLC_BENCH_CLIENT_MEMORY:-3g}
    depends_on:
      pg-local-cache:
        condition: service_healthy
      postgres-plain:
        condition: service_healthy
      valkey:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      PGLC_BENCH_AUTH_TOKEN: ${PGLC_BENCH_AUTH_TOKEN:?PGLC_BENCH_AUTH_TOKEN is required}
      PGLC_BENCH_PG_PASSWORD: ${PGLC_BENCH_POSTGRES_PASSWORD:?PGLC_BENCH_POSTGRES_PASSWORD is required}
      PGLC_BENCH_DURATION: "${PGLC_BENCH_DURATION:-120}"
      PGLC_BENCH_WARMUP_SECONDS: "${PGLC_BENCH_WARMUP_SECONDS:-15}"
      PGLC_BENCH_REPETITIONS: "${PGLC_BENCH_REPETITIONS:-3}"
      PGLC_BENCH_ROW_VALUE_SIZE: "${PGLC_BENCH_ROW_VALUE_SIZE:-}"
      PGLC_BENCH_ROW_PAYLOAD_SIZES: "${PGLC_BENCH_ROW_PAYLOAD_SIZES:-64,512,2048}"
      PGLC_BENCH_ROW_RESP_MIN_OPS: "${PGLC_BENCH_ROW_RESP_MIN_OPS:-10000}"
      PGLC_BENCH_ROW_SQL_MIN_OPS: "${PGLC_BENCH_ROW_SQL_MIN_OPS:-10000}"
      PGLC_BENCH_ROW_WIDTH_MIN_OPS: "${PGLC_BENCH_ROW_WIDTH_MIN_OPS:-0}"
      PGLC_BENCH_CONCURRENCY: "${PGLC_BENCH_CONCURRENCY:-16}"
      PGLC_BENCH_PIPELINE: "${PGLC_BENCH_PIPELINE:-32}"
      PGLC_BENCH_KEYS: "${PGLC_BENCH_KEYS:-16384}"
      PGLC_BENCH_VALUE_SIZE: "${PGLC_BENCH_VALUE_SIZE:-128}"
      PGLC_BENCH_MAX_LATENCY_SAMPLES: "${PGLC_BENCH_MAX_LATENCY_SAMPLES:-200000}"
      PGLC_BENCH_SERVER_CPUS: "${PGLC_BENCH_SERVER_CPUS:-4.0}"
      PGLC_BENCH_CLIENT_CPUS: "${PGLC_BENCH_CLIENT_CPUS:-4.0}"
      PGLC_BENCH_CLIENT_MEMORY: "${PGLC_BENCH_CLIENT_MEMORY:-3g}"
      PGLC_BENCH_SERVER_MEMORY: "${PGLC_BENCH_SERVER_MEMORY:-2g}"
      PGLC_BENCH_PG_LOCAL_CACHE_WORKERS: "${PGLC_BENCH_PG_LOCAL_CACHE_WORKERS:-4}"
      PGLC_BENCH_PG_JOBS: "${PGLC_BENCH_PG_JOBS:-}"
      PGLC_BENCH_POSTGRES_IMAGE: ${PGLC_BENCH_POSTGRES_IMAGE:-postgres:16.14-bookworm}
      PGLC_BENCH_VALKEY_IMAGE: ${PGLC_BENCH_VALKEY_IMAGE:-valkey/valkey:9.1.1-trixie}
      PGLC_BENCH_REDIS_IMAGE: ${PGLC_BENCH_REDIS_IMAGE:-redis:8.8.1-trixie}
      PGLC_BENCH_POSTGRES_IMAGE_IDENTITY: ${PGLC_BENCH_POSTGRES_IMAGE_IDENTITY:-unknown}
      PGLC_BENCH_VALKEY_IMAGE_IDENTITY: ${PGLC_BENCH_VALKEY_IMAGE_IDENTITY:-unknown}
      PGLC_BENCH_REDIS_IMAGE_IDENTITY: ${PGLC_BENCH_REDIS_IMAGE_IDENTITY:-unknown}
      PGLC_BENCH_PGLC_IMAGE: ${PGLC_BENCH_PGLC_IMAGE:-unknown}
      PGLC_BENCH_PG_LOCAL_CACHE_IMAGE_IDENTITY: ${PGLC_BENCH_PG_LOCAL_CACHE_IMAGE_IDENTITY:-unknown}
      PGLC_BENCH_RUNNER_IMAGE: ${PGLC_BENCH_RUNNER_IMAGE:-unknown}
      PGLC_BENCH_RUNNER_IMAGE_IDENTITY: ${PGLC_BENCH_RUNNER_IMAGE_IDENTITY:-unknown}
      PGLC_BENCH_SOURCE_REVISION: ${PGLC_BENCH_SOURCE_REVISION:-unknown}
      PGLC_BENCH_WHOLE_ROW_HARNESS_SHA256: ${PGLC_BENCH_WHOLE_ROW_HARNESS_SHA256:-unknown}
      PGLC_BENCH_DOCKER_VERSION: ${PGLC_BENCH_DOCKER_VERSION:-unknown}
      PGLC_BENCH_COMPOSE_VERSION: ${PGLC_BENCH_COMPOSE_VERSION:-unknown}
      PGLC_BENCH_OUTPUT_DIR: /results
    volumes:
      - type: bind
        source: ${PGLC_BENCH_OUTPUT_DIR:?PGLC_BENCH_OUTPUT_DIR is required}
        target: /results
    networks:
      - benchmark

secrets:
  postgres_password:
    file: ${PGLC_BENCH_SECRET_DIR:?PGLC_BENCH_SECRET_DIR is required}/postgres_password
  pg_local_cache_auth_token:
    file: ${PGLC_BENCH_SECRET_DIR:?PGLC_BENCH_SECRET_DIR is required}/pg_local_cache_auth_token

volumes:
  postgres_data:
  plain_postgres_data:

networks:
  benchmark:
    internal: true
