# ssl_ciphers

> ssl_ciphers is the PostgreSQL setting that defines the list of allowed TLSv1.2 (and lower) ciphers.
---

> [!NOTE]
> **Fact — official short description:** “Sets the list of allowed TLSv1.2 (and lower) ciphers.”

## Identity {#identity}

| Field | Value | Meaning |
| --- | --- | --- |
| Type | `string` | Upstream pg_settings type |
| Context | `sighup` | Takes effect after configuration reload |
| Unit | — | Raw unit |
| Range | — | Raw limits in the last observed version |
| Enum values | — | — for non-enum types |
| Category | Connections and Authentication / SSL | Upstream classification |
| Latest boot value | `HIGH:MEDIUM:+3DES:!aNULL` | HIGH:MEDIUM:+3DES:!aNULL |
{.fields meta="-"}

## Lifecycle {#lifecycle}

| Fact | Value |
| --- | --- |
| First observed | PG9.1 |
| Present in | PG9.1–19 Beta 3 |
| Removed in | No |
| Introduction commit | Not asserted: the name already exists at the 2008 Git-history boundary |
| Commit date | ≤ 2008-01-01 |
| Discussion | — |

## Default history {#default-history}

| Versions | Raw `boot_val` | Unit | Human value |
| --- | --- | --- | --- |
| PG9.1–9.2 | `ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH` | — | ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH |
| PG9.3 | `DEFAULT:!LOW:!EXP:!MD5:@STRENGTH` | — | DEFAULT:!LOW:!EXP:!MD5:@STRENGTH |
| PG9.4–19 Beta 3 | `HIGH:MEDIUM:+3DES:!aNULL` | — | HIGH:MEDIUM:+3DES:!aNULL |
{.full-width caption="Measured PG9.0–19 Beta 3 boot defaults"}

## How it works {#mechanism}

The ssl_ciphers name already exists in PostgreSQL's GUC source at the project's 2008 history boundary and in PG9.0, where it is compiled only under USE_SSL. The audited PG9.0 fallback build does not enable OpenSSL, so the name first appears in the PG9.1 official-image snapshot; that matrix boundary reflects build capability, not the feature's original invention.

The OpenSSL cipher string governs TLS 1.2 and older handshakes. PostgreSQL 18 and later configure TLS 1.3 suites separately with ssl_tls13_ciphers. A SIGHUP reload changes the policy for new TLS contexts and connections but does not renegotiate sessions that are already established.

Treat ssl_ciphers as one part of a complete transport policy with ssl, pg_hba.conf, certificate and key files, CA and revocation settings, protocol floors and ceilings, ssl_groups, and client capabilities. Validate the exact installed OpenSSL build because accepted cipher names and security levels are library-dependent.

## Tuning advice {#tuning-advice}

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

| Workload | Guidance |
| --- | --- |
| OLTP | Treat ssl_ciphers as transport-security policy rather than a performance knob. Follow the organization's TLS baseline and test certificate rotation, reload, and every client class. |
| OLAP | Use the same TLS floor for analytical traffic; benchmark only after correctness because bulk transfer may expose CPU cost but is not a reason to accept obsolete protocols. |
| Small nodes | Keep ssl_ciphers simple and secure, using managed certificates and library defaults reviewed for the installed OpenSSL version. Rehearse renewal before expiry. |
{.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: PG9.1–19 Beta 3 unmodified; OLAP: PG9.1–19 Beta 3 unmodified; CRIT: PG9.1–19 Beta 3 unmodified; TINY: PG9.1–19 Beta 3 unmodified. No Pigsty-specific rationale is inferred from an absent override.

## Common pitfalls {#common-pitfalls}

- Editing ssl_ciphers without reloading configuration and verifying the effective value and subsequent behavior.
- Updating only one TLS file or policy knob and leaving an invalid chain, unreadable key, or incompatible protocol set.
- Assuming a reload renegotiates existing sessions; TLS policy changes affect new handshakes.
- Changing ssl_ciphers globally without a rollback plan and a client or operational compatibility test.

## Related parameters {#related-parameters}

[`ssl_tls13_ciphers`](/parameters/ssl-tls13-ciphers/) · [`ssl_min_protocol_version`](/parameters/ssl-min-protocol-version/) · [`ssl_max_protocol_version`](/parameters/ssl-max-protocol-version/) · [`ssl_prefer_server_ciphers`](/parameters/ssl-prefer-server-ciphers/) · [`ssl_groups`](/parameters/ssl-groups/)

## References {#references}

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