# scram_iterations

> scram_iterations is the PostgreSQL setting that defines the iteration count for SCRAM secret generation.
---

> [!NOTE]
> **Fact — official short description:** “Sets the iteration count for SCRAM secret generation.”

## Identity {#identity}

| Field | Value | Meaning |
| --- | --- | --- |
| Type | `integer` | Upstream pg_settings type |
| Context | `user` | Settable by an ordinary user |
| Unit | — | Raw unit |
| Range | `1` – `2147483647` | Raw limits in the last observed version |
| Enum values | — | — for non-enum types |
| Category | Connections and Authentication / Authentication | Upstream classification |
| Latest boot value | `4096` | 4096 |
{.fields meta="-"}

## Lifecycle {#lifecycle}

| Fact | Value |
| --- | --- |
| First observed | PG16 |
| Present in | PG16–19 Beta 3 |
| Removed in | No |
| Introduction commit | [`b577743000cd`](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=b577743000cd0974052af3a71770a23760423102) — Make SCRAM iteration count configurable |
| Commit date | 2023-03-27 |
| Discussion | [thread 1](https://postgr.es/m/F72E7BC7-189F-4B17-BF47-9735EB72C364@yesql.se) |

## Default history {#default-history}

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

## How it works {#mechanism}

scram_iterations is embedded in every newly generated SCRAM-SHA-256 verifier. Raising it increases offline-guessing cost but also increases legitimate password-setting and authentication work; existing verifiers keep the iteration count with which they were created until their passwords are reset.

It is a USER-context setting, so the session that executes CREATE ROLE or ALTER ROLE determines the count written into the new verifier. Role, database, or application-specific overrides can therefore create a mixture of counts even when postgresql.conf has one value.

PostgreSQL warns that when a role's stored count differs from the configured server value, an unauthenticated observer can distinguish response behavior and infer that the role exists. A count change therefore requires uniform session policy and rotation of all SCRAM verifiers, not only a GUC edit.

## Tuning advice {#tuning-advice}

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

| Workload | Guidance |
| --- | --- |
| OLTP | Choose one count through a security and authentication-latency benchmark, enforce it in every password-management session, and rotate all role passwords so stored verifiers converge. Load-test reconnect storms and failover before raising it. |
| OLAP | Use the same count for analytical roles; workload class is not a reason to expose a distinct verifier count. Schedule credential rotation so long-lived service accounts do not retain the old count. |
| Small nodes | Keep the upstream count unless testing justifies a change. A smaller server should reduce connection churn with pooling, but must still keep all generated verifiers at one consistent count. |
{.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 | Unmodified | — | — |
| OLAP | Unmodified | — | — |
| CRIT | Unmodified | — | — |
| TINY | Unmodified | — | — |
{.full-width}

> [!CAUTION]
> **Advice — pending human review.** Fact from the current Pigsty template projection: OLTP: PG16–19 Beta 3 unmodified; OLAP: PG16–19 Beta 3 unmodified; CRIT: PG16–19 Beta 3 unmodified; TINY: PG16–19 Beta 3 unmodified. No Pigsty-specific rationale is inferred from an absent override.

## Common pitfalls {#common-pitfalls}

- Changing the GUC without resetting existing passwords; their verifiers retain the old count.
- Allowing role or database session defaults to generate verifiers with counts different from postgresql.conf, creating a role-existence side channel.
- Raising the count without load-testing authentication storms, failover, pooler reconnects, and password rotation jobs.
- Assuming a higher count repairs weak passwords or compensates for leaked verifier material.

## Related parameters {#related-parameters}

[`password_encryption`](/parameters/password-encryption/) · [`md5_password_warnings`](/parameters/md5-password-warnings/) · [`authentication_timeout`](/parameters/authentication-timeout/) · [`oauth_validator_libraries`](/parameters/oauth-validator-libraries/) · [`krb_server_keyfile`](/parameters/krb-server-keyfile/)

## References {#references}

- [PostgreSQL 19 Beta 3 — scram_iterations](https://www.postgresql.org/docs/19/runtime-config-connection.html#GUC-SCRAM-ITERATIONS)
- [PostgreSQL 19 release notes](https://www.postgresql.org/docs/19/release-19.html)
- [Machine-readable GUC export](/data/guc.jsonl)
