Skip to content

Commit 58ca074

Browse files
committed
Add application_name option and TLS session cache to pg client
1 parent ed6dfb5 commit 58ca074

2 files changed

Lines changed: 42 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313

1414
- **pg**: `WithMaxConnLifetimeJitter` option to smear connection recycle events and avoid synchronized reconnect storms. Defaults to 5 minutes; pass `0` to disable.
1515
- **pg**: `WithHealthCheckPeriod` option to tune how often the pool checks idle connections and enforces MinConns/MaxConnIdleTime/MaxConnLifetime. A zero value leaves the pgx default (1 minute) in place.
16+
- **pg**: `WithApplicationName` option to set the PostgreSQL `application_name` runtime parameter, surfacing the client in `pg_stat_activity`, `pg_stat_statements`, server logs, and `pg_locks` for easier incident attribution.
17+
18+
### Changed
19+
20+
- **pg**: TLS configurations produced by `WithTLS` and `WithUnsecureTLS` now enable a client session cache, allowing reconnects to resume previous TLS sessions and skip the full handshake. Reduces tail latency on `pgxpool_acquire_duration_seconds` for WAN-reached databases.
1621

1722
## [0.8.0] - 2026-05-08
1823

pg/client.go

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ type (
4848
// Client provides a PostgreSQL client with a connection pool,
4949
// logging, tracing, and Prometheus metrics registration.
5050
Client struct {
51-
addr string
52-
user string
53-
password string
54-
database string
51+
addr string
52+
user string
53+
password string
54+
database string
55+
applicationName string
5556

5657
debug bool
5758

@@ -116,8 +117,32 @@ func WithDatabase(database string) Option {
116117
}
117118
}
118119

120+
// WithApplicationName sets the PostgreSQL application_name runtime
121+
// parameter on every connection in the pool. This value is exposed by
122+
// the server in pg_stat_activity, pg_stat_statements, log lines, and
123+
// pg_locks, making it the primary handle for identifying the source
124+
// of a query during incident response.
125+
//
126+
// PostgreSQL truncates application_name to NAMEDATALEN-1 (63 bytes by
127+
// default) silently, so prefer short, stable identifiers such as the
128+
// service name. An empty string leaves the runtime parameter unset
129+
// (which falls back to whatever the libpq env, e.g. PGAPPNAME, or the
130+
// server defaults choose).
131+
func WithApplicationName(name string) Option {
132+
return func(c *Client) {
133+
c.applicationName = name
134+
}
135+
}
136+
119137
// WithTLS configures TLS using the provided certificates for secure
120138
// connections.
139+
//
140+
// The returned config enables a TLS client session cache so that
141+
// reconnects (after MaxConnLifetime recycles, failovers, or pool
142+
// refills) can resume a previous session and skip the full handshake.
143+
// This noticeably reduces tail latency on pgxpool_acquire_duration_seconds
144+
// for deployments where the database is reached over WAN or any link
145+
// where the round-trip cost dominates connection construction.
121146
func WithTLS(certs []*x509.Certificate) Option {
122147
return func(c *Client) {
123148
rootCAs := x509.NewCertPool()
@@ -137,6 +162,7 @@ func WithTLS(certs []*x509.Certificate) Option {
137162
InsecureSkipVerify: false,
138163
ServerName: host,
139164
MinVersion: tls.VersionTLS12,
165+
ClientSessionCache: tls.NewLRUClientSessionCache(0),
140166
}
141167
}
142168
}
@@ -149,6 +175,7 @@ func WithUnsecureTLS() Option {
149175
c.tlsConfig = &tls.Config{
150176
InsecureSkipVerify: true,
151177
MinVersion: tls.VersionTLS12,
178+
ClientSessionCache: tls.NewLRUClientSessionCache(0),
152179
}
153180
}
154181
}
@@ -302,6 +329,12 @@ func NewClient(options ...Option) (*Client, error) {
302329
config.ConnConfig.Password = c.password
303330
config.ConnConfig.Database = c.database
304331
config.ConnConfig.TLSConfig = c.tlsConfig
332+
if c.applicationName != "" {
333+
if config.ConnConfig.RuntimeParams == nil {
334+
config.ConnConfig.RuntimeParams = map[string]string{}
335+
}
336+
config.ConnConfig.RuntimeParams["application_name"] = c.applicationName
337+
}
305338
config.MinConns = c.minPoolSize
306339
config.MaxConns = c.poolSize
307340
if c.maxConnIdleTime > 0 {

0 commit comments

Comments
 (0)