ACE Configuration

July 7, 2026 · View on GitHub

Before using ACE commands, you must provide connection and cluster information in the ace.yaml and pg_service.conf files.

ACE first attempts to use the Postgres service file to resolve connection information before falling back to the (legacy) <cluster>.json file for cluster details. Before invoking any ACE commands, use the following commands to create the configuration files:

./ace cluster init --path pg_service.conf
./ace config init --path ace.yaml

!!! info

You must create and modify the configuration files before using either standard ACE API calls or mtree calls. A Postgres service file (or a legacy cluster definition JSON file) and a configuration file named `ace.yaml` are both required when running ACE.

The ace.yaml file

The ace.yaml file defines default values used when calling the ACE commands. The file contains properties that control the resources used by ACE commands; after creating the ace.yaml file, use your choice of editor to customize the properties for your system:

Section --> PropertyDescription
postgres --> statement_timeoutEquivalent to Postgres statement_timeout. Aborts any query that exceeds the specified time (ms). 0 disables and is the default. Set a non-zero value to guard long-running operations.
postgres --> connection_timeoutEquivalent to Postgres connect_timeout. Max wait to connect (s). 0 = wait indefinitely. Default: 10
postgres --> application_nameValue reported in application_name. Default: "ACE"
postgres --> tcp_keepalives_idleTCP keepalive idle time (s). Default: 30
postgres --> tcp_keepalives_intervalTCP keepalive interval (s). Default: 10
postgres --> tcp_keepalives_countNumber of keepalive probes before drop. Default: 5
table_diff --> concurrency_factorCPU ratio for diff concurrency (0.0–4.0, e.g. 0.5 uses half of available CPUs). Default: 0.5
table_diff --> min_diff_block_sizeMinimum diff block (row chunk) size. Default: 1
table_diff --> max_diff_block_sizeMaximum diff block size. Default: 1000000
table_diff --> compare_unit_sizeUnit size for smallest comparison chunk. Default: 10000
table_diff --> max_connectionsMaximum database connections per node during diff operations. When set, caps the connection pool regardless of concurrency factor. Default: 0 (derive from concurrency factor)
mtree → cdc --> slot_nameLogical decoding slot name for mtree CDC. Default: "ace_mtree_slot"
mtree → cdc --> publication_namePublication used for mtree CDC. Default: "ace_mtree_pub"
mtree → cdc --> cdc_processing_timeoutWall-clock budget (s) for a CDC catch-up drain before it gives up. Progress is durable, so a timeout means "re-run or raise", not "rebuild". Default: 300
mtree → cdc --> cdc_metadata_flush_secondsHow often (s) CDC metadata is flushed to disk. Default: 10
mtree → cdc --> cdc_flush_batch_sizePeak un-committed CDC changes a bounded drain buffers before applying them to the tree and freeing memory. Only primary keys are buffered, so memory scales with key size, not row width. Default: 10000
mtree → cdc --> adaptive_drain_fractionDuring a bounded CDC drain (mtree update / mtree table-diff), a table whose decoded UPDATE count exceeds max(adaptive_drain_min_changes, adaptive_drain_fraction × table row estimate) is escalated: instead of per-update block marking, all of its Merkle-tree blocks are marked dirty once and rehashed in bulk from live data on the following tree update. Inserts and deletes are always tracked individually regardless of escalation, so block split/merge maintenance is unaffected. This bounds drain cost for heavily-updated tables (a bulk rehash costs about as much as a tree build, while per-change marking grows linearly with the backlog). Set to -1 to disable escalation; 0 is treated as use-the-default (0.01), so to escalate on the adaptive_drain_min_changes floor alone, set a very small positive fraction rather than 0. Escalation never affects correctness — block hashes are always recomputed from live table data. Default: 0.01
mtree → cdc --> adaptive_drain_min_changesFloor for the escalation threshold, so small tables and modest change volumes always use the precise per-change path. Default: 1000
mtree --> schemaSchema used for mtree metadata/objects. Default: "pgedge_ace"
mtree → diff --> min_block_sizeMinimum Merkle diff block size. Default: 1000
mtree → diff --> block_sizeTarget Merkle diff block size. Default: 100000
mtree → diff --> max_block_sizeMaximum Merkle diff block size. Default: 1000000
server --> listen_addressAddress the ACE server listens on. Default: "0.0.0.0"
server --> listen_portPort the ACE server listens on. Default: 5000
(root) --> schedule_jobsArray of job definitions consumed by the scheduler (see Scheduling ACE Runs). Default: []
(root) --> schedule_configArray of cadence settings (run_frequency or crontab_schedule) that reference entries in schedule_jobs. Default: []
cert_auth --> use_cert_authUse client certificate authentication. Default: true
cert_auth --> ace_user_cert_filePath to user/client certificate. Default: "data/pg16/pki/admin-cert/admin.crt"
cert_auth --> ace_user_key_filePath to user/client private key. Default: "data/pg16/pki/admin-cert/admin.key"
cert_auth --> ca_cert_filePath to CA certificate. Default: "data/pg16/pki/ca.crt"
(root) --> debug_modeEnable verbose/diagnostic logging. Default: false

The pg_service.conf File

ACE uses the pg_service.conf file to find cluster and node details.

ACE checks the following locations in this order:

  1. The ACE_PGSERVICEFILE environment variable.
  2. The PGSERVICEFILE environment variable.
  3. The pg_service.conf file in the current directory.
  4. $HOME/.pg_service.conf.
  5. /etc/pg_service.conf.

After creating the file, add a base section named after the cluster (for example [acctg]) to capture shared options, and one section per node named in the form: <cluster>.<node>, such as [acctg.n1]. Then, update the template with the host, port, database, and credentials for each node before running ACE commands.

[acctg]
host=10.0.0.1
port=5432
dbname=acctg
user=rocky
password=1safepassword!
[acctg.n1]
host=10.0.0.2
port=5432
dbname=acctg
user=rocky
password=1safepassword!
[acctg.n2]
host=10.0.0.3
port=5432
dbname=acctg
user=rocky
password=1safepassword!

If none of these files contain entries for the requested cluster, ACE attempts to read the <cluster>.json file.