Compare commits

...

3 Commits

Author SHA1 Message Date
Danny Kopping 046c0108b6 chore: remove "auto" feature
Signed-off-by: Danny Kopping <danny@coder.com>
2026-01-19 18:31:42 +02:00
Danny Kopping fb6cac93b7 chore: make lint/markdown
Signed-off-by: Danny Kopping <danny@coder.com>
2026-01-19 18:18:22 +02:00
Danny Kopping 77ef84758d chore: increase default pg settings in line with observed usage
Signed-off-by: Danny Kopping <danny@coder.com>
2026-01-19 17:38:31 +02:00
13 changed files with 32 additions and 191 deletions
+1 -4
View File
@@ -748,10 +748,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
var pubsubWatchdogTimeout <-chan struct{}
maxOpenConns := int(vals.PostgresConnMaxOpen.Value())
maxIdleConns, err := codersdk.ComputeMaxIdleConns(maxOpenConns, vals.PostgresConnMaxIdle.Value())
if err != nil {
return xerrors.Errorf("compute max idle connections: %w", err)
}
maxIdleConns := int(vals.PostgresConnMaxIdle.Value())
logger.Debug(ctx, "creating database connection pool", slog.F("max_open_conns", maxOpenConns), slog.F("max_idle_conns", maxIdleConns))
sqlDB, dbURL, err := getAndMigratePostgresDB(ctx, logger, vals.PostgresURL.String(), codersdk.PostgresAuth(vals.PostgresAuth), sqlDriver,
WithMaxOpenConns(maxOpenConns),
+4 -5
View File
@@ -65,12 +65,11 @@ OPTIONS:
Type of auth to use when connecting to postgres. For AWS RDS, using
IAM authentication (awsiamrds) is recommended.
--postgres-conn-max-idle string, $CODER_PG_CONN_MAX_IDLE (default: auto)
Maximum number of idle connections to the database. Set to "auto" (the
default) to use max open / 3. Value must be greater or equal to 0; 0
means explicitly no idle connections.
--postgres-conn-max-idle int, $CODER_PG_CONN_MAX_IDLE (default: 15)
Maximum number of idle connections to the database. Value must be
greater or equal to 0; 0 means explicitly no idle connections.
--postgres-conn-max-open int, $CODER_PG_CONN_MAX_OPEN (default: 10)
--postgres-conn-max-open int, $CODER_PG_CONN_MAX_OPEN (default: 30)
Maximum number of open connections to the database. Defaults to 10.
--postgres-url string, $CODER_PG_CONNECTION_URL
+6 -7
View File
@@ -484,13 +484,12 @@ ephemeralDeployment: false
# (default: password, type: enum[password\|awsiamrds])
pgAuth: password
# Maximum number of open connections to the database. Defaults to 10.
# (default: 10, type: int)
pgConnMaxOpen: 10
# Maximum number of idle connections to the database. Set to "auto" (the default)
# to use max open / 3. Value must be greater or equal to 0; 0 means explicitly no
# idle connections.
# (default: auto, type: string)
pgConnMaxIdle: auto
# (default: 30, type: int)
pgConnMaxOpen: 30
# Maximum number of idle connections to the database. Value must be greater or
# equal to 0; 0 means explicitly no idle connections.
# (default: 15, type: int)
pgConnMaxIdle: 15
# A URL to an external Terms of Service that must be accepted by users when
# logging in.
# (default: <unset>, type: string)
+1 -1
View File
@@ -14481,7 +14481,7 @@ const docTemplate = `{
"type": "string"
},
"pg_conn_max_idle": {
"type": "string"
"type": "integer"
},
"pg_conn_max_open": {
"type": "integer"
+1 -1
View File
@@ -13051,7 +13051,7 @@
"type": "string"
},
"pg_conn_max_idle": {
"type": "string"
"type": "integer"
},
"pg_conn_max_open": {
"type": "integer"
+4 -33
View File
@@ -442,10 +442,6 @@ var PostgresAuthDrivers = []string{
string(PostgresAuthAWSIAMRDS),
}
// PostgresConnMaxIdleAuto is the value for auto-computing max idle connections
// based on max open connections.
const PostgresConnMaxIdleAuto = "auto"
// DeploymentValues is the central configuration values the coder server.
type DeploymentValues struct {
Verbose serpent.Bool `json:"verbose,omitempty"`
@@ -467,7 +463,7 @@ type DeploymentValues struct {
PostgresURL serpent.String `json:"pg_connection_url,omitempty" typescript:",notnull"`
PostgresAuth string `json:"pg_auth,omitempty" typescript:",notnull"`
PostgresConnMaxOpen serpent.Int64 `json:"pg_conn_max_open,omitempty" typescript:",notnull"`
PostgresConnMaxIdle serpent.String `json:"pg_conn_max_idle,omitempty" typescript:",notnull"`
PostgresConnMaxIdle serpent.Int64 `json:"pg_conn_max_idle,omitempty" typescript:",notnull"`
OAuth2 OAuth2Config `json:"oauth2,omitempty" typescript:",notnull"`
OIDC OIDCConfig `json:"oidc,omitempty" typescript:",notnull"`
Telemetry TelemetryConfig `json:"telemetry,omitempty" typescript:",notnull"`
@@ -2634,7 +2630,7 @@ func (c *DeploymentValues) Options() serpent.OptionSet {
Description: "Maximum number of open connections to the database. Defaults to 10.",
Flag: "postgres-conn-max-open",
Env: "CODER_PG_CONN_MAX_OPEN",
Default: "10",
Default: "30",
Value: serpent.Validate(&c.PostgresConnMaxOpen, func(value *serpent.Int64) error {
if value.Value() <= 0 {
return xerrors.New("must be greater than zero")
@@ -2645,11 +2641,11 @@ func (c *DeploymentValues) Options() serpent.OptionSet {
},
{
Name: "Postgres Connection Max Idle",
Description: "Maximum number of idle connections to the database. Set to \"auto\" (the default) to use max open / 3. " +
Description: "Maximum number of idle connections to the database. " +
"Value must be greater or equal to 0; 0 means explicitly no idle connections.",
Flag: "postgres-conn-max-idle",
Env: "CODER_PG_CONN_MAX_IDLE",
Default: PostgresConnMaxIdleAuto,
Default: "15",
Value: &c.PostgresConnMaxIdle,
YAML: "pgConnMaxIdle",
},
@@ -4203,28 +4199,3 @@ func (c CryptoKey) CanVerify(now time.Time) bool {
beforeDelete := c.DeletesAt.IsZero() || now.Before(c.DeletesAt)
return hasSecret && beforeDelete
}
// ComputeMaxIdleConns calculates the effective maxIdleConns value. If
// configuredIdle is "auto", it returns maxOpen/3 with a minimum of 1. If
// configuredIdle exceeds maxOpen, it returns an error.
func ComputeMaxIdleConns(maxOpen int, configuredIdle string) (int, error) {
configuredIdle = strings.TrimSpace(configuredIdle)
if configuredIdle == PostgresConnMaxIdleAuto {
computed := maxOpen / 3
if computed < 1 {
return 1, nil
}
return computed, nil
}
idle, err := strconv.Atoi(configuredIdle)
if err != nil {
return 0, xerrors.Errorf("invalid max idle connections %q: must be %q or >= 0", configuredIdle, PostgresConnMaxIdleAuto)
}
if idle < 0 {
return 0, xerrors.Errorf("max idle connections must be %q or >= 0", PostgresConnMaxIdleAuto)
}
if idle > maxOpen {
return 0, xerrors.Errorf("max idle connections (%d) cannot exceed max open connections (%d)", idle, maxOpen)
}
return idle, nil
}
-117
View File
@@ -765,120 +765,3 @@ func TestRetentionConfigParsing(t *testing.T) {
})
}
}
func TestComputeMaxIdleConns(t *testing.T) {
t.Parallel()
tests := []struct {
name string
maxOpen int
configuredIdle string
expectedIdle int
expectError bool
errorContains string
}{
{
name: "auto_default_10_open",
maxOpen: 10,
configuredIdle: "auto",
expectedIdle: 3, // 10/3 = 3
},
{
name: "auto_with_whitespace",
maxOpen: 10,
configuredIdle: " auto ",
expectedIdle: 3, // 10/3 = 3
},
{
name: "auto_30_open",
maxOpen: 30,
configuredIdle: "auto",
expectedIdle: 10, // 30/3 = 10
},
{
name: "auto_minimum_1",
maxOpen: 1,
configuredIdle: "auto",
expectedIdle: 1, // 1/3 = 0, but minimum is 1
},
{
name: "auto_minimum_2_open",
maxOpen: 2,
configuredIdle: "auto",
expectedIdle: 1, // 2/3 = 0, but minimum is 1
},
{
name: "auto_3_open",
maxOpen: 3,
configuredIdle: "auto",
expectedIdle: 1, // 3/3 = 1
},
{
name: "explicit_equal_to_max",
maxOpen: 10,
configuredIdle: "10",
expectedIdle: 10,
},
{
name: "explicit_less_than_max",
maxOpen: 10,
configuredIdle: "5",
expectedIdle: 5,
},
{
name: "explicit_with_whitespace",
maxOpen: 10,
configuredIdle: " 5 ",
expectedIdle: 5,
},
{
name: "explicit_0",
maxOpen: 10,
configuredIdle: "0",
expectedIdle: 0,
},
{
name: "error_exceeds_max",
maxOpen: 10,
configuredIdle: "15",
expectError: true,
errorContains: "cannot exceed",
},
{
name: "error_exceeds_max_by_1",
maxOpen: 10,
configuredIdle: "11",
expectError: true,
errorContains: "cannot exceed",
},
{
name: "error_invalid_string",
maxOpen: 10,
configuredIdle: "invalid",
expectError: true,
errorContains: "must be \"auto\" or >= 0",
},
{
name: "error_negative",
maxOpen: 10,
configuredIdle: "-1",
expectError: true,
errorContains: "must be \"auto\" or >= 0",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
result, err := codersdk.ComputeMaxIdleConns(tt.maxOpen, tt.configuredIdle)
if tt.expectError {
require.Error(t, err)
require.Contains(t, err.Error(), tt.errorContains)
} else {
require.NoError(t, err)
require.Equal(t, tt.expectedIdle, result)
}
})
}
}
+1 -1
View File
@@ -439,7 +439,7 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \
"username_field": "string"
},
"pg_auth": "string",
"pg_conn_max_idle": "string",
"pg_conn_max_idle": 0,
"pg_conn_max_open": 0,
"pg_connection_url": "string",
"pprof": {
+3 -3
View File
@@ -2915,7 +2915,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
"username_field": "string"
},
"pg_auth": "string",
"pg_conn_max_idle": "string",
"pg_conn_max_idle": 0,
"pg_conn_max_open": 0,
"pg_connection_url": "string",
"pprof": {
@@ -3462,7 +3462,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
"username_field": "string"
},
"pg_auth": "string",
"pg_conn_max_idle": "string",
"pg_conn_max_idle": 0,
"pg_conn_max_open": 0,
"pg_connection_url": "string",
"pprof": {
@@ -3654,7 +3654,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
| `oauth2` | [codersdk.OAuth2Config](#codersdkoauth2config) | false | | |
| `oidc` | [codersdk.OIDCConfig](#codersdkoidcconfig) | false | | |
| `pg_auth` | string | false | | |
| `pg_conn_max_idle` | string | false | | |
| `pg_conn_max_idle` | integer | false | | |
| `pg_conn_max_open` | integer | false | | |
| `pg_connection_url` | string | false | | |
| `pprof` | [codersdk.PprofConfig](#codersdkpprofconfig) | false | | |
+4 -4
View File
@@ -1022,7 +1022,7 @@ Type of auth to use when connecting to postgres. For AWS RDS, using IAM authenti
| Type | <code>int</code> |
| Environment | <code>$CODER_PG_CONN_MAX_OPEN</code> |
| YAML | <code>pgConnMaxOpen</code> |
| Default | <code>10</code> |
| Default | <code>30</code> |
Maximum number of open connections to the database. Defaults to 10.
@@ -1030,12 +1030,12 @@ Maximum number of open connections to the database. Defaults to 10.
| | |
|-------------|--------------------------------------|
| Type | <code>string</code> |
| Type | <code>int</code> |
| Environment | <code>$CODER_PG_CONN_MAX_IDLE</code> |
| YAML | <code>pgConnMaxIdle</code> |
| Default | <code>auto</code> |
| Default | <code>15</code> |
Maximum number of idle connections to the database. Set to "auto" (the default) to use max open / 3. Value must be greater or equal to 0; 0 means explicitly no idle connections.
Maximum number of idle connections to the database. Value must be greater or equal to 0; 0 means explicitly no idle connections.
### --secure-auth-cookie
+2 -2
View File
@@ -224,12 +224,12 @@ Coder Server maintains a pool of connections to PostgreSQL. You can tune the
pool size with these settings:
- `--postgres-conn-max-open` (env: `CODER_PG_CONN_MAX_OPEN`): Maximum number of open
connections. Default: 10. Ensure that your PostgreSQL Server has `max_connections`
connections. Default: 30. Ensure that your PostgreSQL Server has `max_connections`
set appropriately to accommodate all Coder Server replicas multiplied by the
maximum number of open connections. We recommend configuring an additional 20%
of connections to account for churn and other clients.
- `--postgres-conn-max-idle` (env: `CODER_PG_CONN_MAX_IDLE`): Maximum number of idle
connections kept in the pool. Default: "auto", which uses max open / 3.
connections kept in the pool. Default: 15.
When a connection is returned to the pool and the idle pool is already full, the
connection is closed immediately. This can cause connection establishment
+4 -5
View File
@@ -66,12 +66,11 @@ OPTIONS:
Type of auth to use when connecting to postgres. For AWS RDS, using
IAM authentication (awsiamrds) is recommended.
--postgres-conn-max-idle string, $CODER_PG_CONN_MAX_IDLE (default: auto)
Maximum number of idle connections to the database. Set to "auto" (the
default) to use max open / 3. Value must be greater or equal to 0; 0
means explicitly no idle connections.
--postgres-conn-max-idle int, $CODER_PG_CONN_MAX_IDLE (default: 15)
Maximum number of idle connections to the database. Value must be
greater or equal to 0; 0 means explicitly no idle connections.
--postgres-conn-max-open int, $CODER_PG_CONN_MAX_OPEN (default: 10)
--postgres-conn-max-open int, $CODER_PG_CONN_MAX_OPEN (default: 30)
Maximum number of open connections to the database. Defaults to 10.
--postgres-url string, $CODER_PG_CONNECTION_URL
+1 -8
View File
@@ -1741,7 +1741,7 @@ export interface DeploymentValues {
readonly pg_connection_url?: string;
readonly pg_auth?: string;
readonly pg_conn_max_open?: number;
readonly pg_conn_max_idle?: string;
readonly pg_conn_max_idle?: number;
readonly oauth2?: OAuth2Config;
readonly oidc?: OIDCConfig;
readonly telemetry?: TelemetryConfig;
@@ -3582,13 +3582,6 @@ export type PostgresAuth = "awsiamrds" | "password";
export const PostgresAuths: PostgresAuth[] = ["awsiamrds", "password"];
// From codersdk/deployment.go
/**
* PostgresConnMaxIdleAuto is the value for auto-computing max idle connections
* based on max open connections.
*/
export const PostgresConnMaxIdleAuto = "auto";
// From codersdk/deployment.go
export interface PprofConfig {
readonly enable: boolean;