# autovacuum_vacuum_scale_factor

> Controls the table-size-proportional part of the normal autovacuum VACUUM trigger. Lower values make large tables eligible after a smaller fraction of rows becomes obsolete.
---

> [!NOTE]
> **Fact — official short description:** “Number of tuple updates or deletes prior to vacuum as a fraction of reltuples.”

## Identity {#identity}

| Field | Value | Meaning |
| --- | --- | --- |
| Type | `real` | Upstream pg_settings type |
| Context | `sighup` | Takes effect after configuration reload |
| Unit | — | Raw unit |
| Range | `0` – `100` | Raw limits in the last observed version |
| Enum values | — | — for non-enum types |
| Category | Vacuuming / Automatic Vacuuming | Upstream classification |
| Latest boot value | `0.2` | 0.2 |
{.fields meta="-"}

## Lifecycle {#lifecycle}

| Fact | Value |
| --- | --- |
| First observed | PG9.0 (research boundary) |
| Present in | PG9.0–19 Beta 3 |
| Removed in | No |
| Introduction commit | Not asserted: predates the PG9.0 research boundary |
| Commit date | — |
| Discussion | — |

## Default history {#default-history}

| Versions | Raw `boot_val` | Unit | Human value |
| --- | --- | --- | --- |
| PG9.0–19 Beta 3 | `0.2` | — | 0.2 |
{.full-width caption="Measured PG9.0–19 Beta 3 boot defaults"}

## How it works {#mechanism}

The core trigger is the base threshold plus this factor multiplied by pg_class.reltuples, an approximate row count. In PostgreSQL 18 the result is also capped by autovacuum_vacuum_max_threshold.

This trigger counts tuples made obsolete by UPDATE or DELETE; insert-driven vacuuming has its own threshold and scale factor. Anti-wraparound vacuuming is governed by transaction-age rules and can run independently of this setting.

A table-level autovacuum_vacuum_scale_factor storage parameter overrides the global value, which is often preferable when table sizes and update rates vary widely.

## Tuning advice {#tuning-advice}

> [!TIP]
> **Advice.** These are workload-specific starting points and must be validated with measurements.

| Workload | Guidance |
| --- | --- |
| OLTP | Use lower per-table values on large, update-heavy tables so dead tuples do not accumulate into a large absolute backlog. Validate with table churn and vacuum duration rather than selecting a percentage in isolation. |
| OLAP | For append-and-batch workloads, coordinate the threshold with load cycles and explicit VACUUM/ANALYZE. A low global factor can create unwanted maintenance during bulk jobs. |
| Small nodes | The upstream default is often adequate for genuinely small tables. Tune exceptions per table; a low cluster-wide value can create frequent tiny vacuums. |
{.full-width}

## Pigsty {#pigsty}

Values use the fixed 8-vCPU, 32-GiB, 100-GiB SSD fixture and render the current Pigsty templates for PG19 Beta 3; this does not assert current Pigsty support for that historical or beta release.

| Template | Effective value | Versus upstream boot | Source expression |
| --- | --- | --- | --- |
| OLTP | `0.08` | different | `0.08` |
| OLAP | `0.08` | different | `0.08` |
| CRIT | `0.08` | different | `0.08` |
| TINY | Unmodified | — | — |
{.full-width}

> [!CAUTION]
> **Advice — pending human review.** Fact from the current Pigsty template projection: OLTP: PG9.0–19 Beta 3 = 0.08 (dcs); OLAP: PG9.0–19 Beta 3 = 0.08 (dcs); CRIT: PG9.0–19 Beta 3 = 0.08 (dcs); TINY: PG9.0–19 Beta 3 unmodified. Advice, pending human review — Editorial hypothesis, pending maintainer review: the larger profiles favor earlier cleanup to bound absolute dead-tuple accumulation on sizable tables; TINY avoids extra vacuum frequency on constrained systems.

## Common pitfalls {#common-pitfalls}

- A percentage that looks small can still represent millions of dead tuples on a large table.
- Lowering the factor globally can create continuous I/O pressure across many tables.
- It does not control insert-triggered vacuuming or anti-wraparound vacuuming.
- reltuples is an estimate, so the trigger is not an exact dead-row percentage.
- Table storage parameters can silently make the global value irrelevant for that table.

## Related parameters {#related-parameters}

[`autovacuum_vacuum_threshold`](/parameters/autovacuum-vacuum-threshold/) · [`autovacuum_vacuum_max_threshold`](/parameters/autovacuum-vacuum-max-threshold/) · [`autovacuum_vacuum_insert_scale_factor`](/parameters/autovacuum-vacuum-insert-scale-factor/) · [`autovacuum_analyze_scale_factor`](/parameters/autovacuum-analyze-scale-factor/) · [`autovacuum_naptime`](/parameters/autovacuum-naptime/) · [`autovacuum_freeze_max_age`](/parameters/autovacuum-freeze-max-age/)

## References {#references}

- [PostgreSQL 19 Beta 3 — autovacuum_vacuum_scale_factor](https://www.postgresql.org/docs/19/runtime-config-vacuum.html#GUC-AUTOVACUUM-VACUUM-SCALE-FACTOR)
- [PostgreSQL 18: Autovacuum trigger formulas](https://www.postgresql.org/docs/18/routine-vacuuming.html#AUTOVACUUM)
- [PostgreSQL 19 release notes](https://www.postgresql.org/docs/19/release-19.html)
- [Machine-readable GUC export](/data/guc.jsonl)
