Skip to content

feat: allow overwriting deployment updateStrategy and configuration parameters#293

Open
hebestreit wants to merge 1 commit intoopenfga:mainfrom
hebestreit:feat/update-strategy
Open

feat: allow overwriting deployment updateStrategy and configuration parameters#293
hebestreit wants to merge 1 commit intoopenfga:mainfrom
hebestreit:feat/update-strategy

Conversation

@hebestreit
Copy link
Copy Markdown

@hebestreit hebestreit commented Mar 19, 2026

Description

What problem is being solved?

We configured OPENFGA_DATASTORE_MIN_OPEN_CONNS=45 and distributed the setting to all three replicas. When restarting the Deployment or doing a rolling upgrade, a fourth pod is started and fails with below error since there are no database connections available anymore.

panic: initialize postgres datastore: configure primary db: ping db: failed to connect to `user=openfga database=openfga`:
        10.xxx.xx.xx:5432 (postgresql.example.org): server error: FATAL: remaining connection slots are reserved for roles with privileges of the "pg_use_reserved_connections" role (SQLSTATE 53300)
        10.xxx.xx.xx::5432 (postgresql.example.org): server error: FATAL: no pg_hba.conf entry for host "10.xxx.xx.xx:", user "openfga", database "openfga", no encryption (SQLSTATE 28000)

goroutine 1 [running]:
github.com/openfga/openfga/cmd/run.run(0x31736b72b508?, {0x3ebdc80?, 0x4?, 0x2572720?})
    github.com/openfga/openfga/cmd/run/run.go:401 +0xdd
github.com/spf13/cobra.(*Command).execute(0x31736b72b508, {0x3ebdc80, 0x0, 0x0})
    github.com/spf13/cobra@v1.10.2/command.go:1019 +0xafb
github.com/spf13/cobra.(*Command).ExecuteC(0x31736b72b208)
    github.com/spf13/cobra@v1.10.2/command.go:1148 +0x465
github.com/spf13/cobra.(*Command).Execute(0x31736b72b208?)
    github.com/spf13/cobra@v1.10.2/command.go:1071 +0x13
main.main()
    github.com/openfga/openfga/cmd/openfga/main.go:28 +0x10f

How is it being solved?

Allow the user to set the Deployment strategy and additional configuration parameters like:

  • maxSurge that specifies the maximum number of Pods that can be created over the desired number of Pods.
  • maxUnavailable that specifies the maximum number of Pods that can be unavailable during the update process.

The implementation can be tested by running below commands.

Overwrite

helm template openfga openfga --set updateStrategy.rollingUpdate.maxSurge=0 --set updateStrategy.rollingUpdate.maxUnavailable=1 | grep -5 RollingUpdate
spec:
  strategy:
    rollingUpdate:
      maxSurge: 0
      maxUnavailable: 1
    type: RollingUpdate
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: openfga
      app.kubernetes.io/instance: openfga

Default behavior

helm template openfga openfga | grep -5 RollingUpdate
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/part-of: openfga
spec:
  strategy:
    rollingUpdate: {}
    type: RollingUpdate
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: openfga
      app.kubernetes.io/instance: openfga

What changes are made to solve it?

Updated the deployment.yaml and allowed to overwrite the configuration via values.yaml.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "openfga.fullname" . }}
  labels:
    {{- include "openfga.labels" . | nindent 4 }}
  {{- with .Values.annotations }}
  annotations:
    {{- toYaml . | nindent 4 }}
  {{- end }}
spec:
  {{- if .Values.updateStrategy }}
  strategy: {{- toYaml .Values.updateStrategy | nindent 4 }}
  {{- end }}#
  # ...

References

Review Checklist

  • I have clicked on "allow edits by maintainers".
  • I have added documentation for new/changed functionality in this PR or in a PR to openfga.dev [Provide a link to any relevant PRs in the references section above]
  • The correct base branch is being used, if not main
  • I have added tests to validate that the change in functionality is working as expected

Summary by CodeRabbit

New Features

  • Deployment update strategy is now fully configurable via Helm chart values. Users can directly specify their preferred strategy type and rolling update parameters through configuration values, enabling customization of how OpenFGA pods are updated during deployments. Rolling update strategy is configured as the default for reliable and seamless service updates.

@hebestreit hebestreit requested review from a team as code owners March 19, 2026 11:56
Copilot AI review requested due to automatic review settings March 19, 2026 11:56
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla bot commented Mar 19, 2026

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: hebestreit / name: Daniel Hebestreit (538d899)

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 19, 2026

Walkthrough

The pull request adds configurable Kubernetes deployment update strategy support to the OpenFGA Helm chart. Three related files are modified to introduce a new updateStrategy values parameter that allows users to specify rolling update strategy configurations through Helm values, with appropriate schema validation and default values.

Changes

Cohort / File(s) Summary
Helm Chart Update Strategy
charts/openfga/templates/deployment.yaml, charts/openfga/values.schema.json, charts/openfga/values.yaml
Added updateStrategy configuration support: template now conditionally includes strategy field based on .Values.updateStrategy; schema defines updateStrategy with type (string, default "RollingUpdate") and rollingUpdate (object); default values file specifies RollingUpdate strategy.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: allowing users to configure the deployment update strategy via Helm values, which is the core objective of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can disable sequence diagrams in the walkthrough.

Disable the reviews.sequence_diagrams setting to disable sequence diagrams in the walkthrough.

@hebestreit hebestreit changed the title feat: allow overwriting deployment updateStrategy feat: allow overwriting deployment updateStrategy and configuration parameters Mar 19, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
charts/openfga/values.schema.json (1)

33-47: Consider adding validation constraints to the schema.

The schema could be more specific to provide better validation and documentation:

  1. The type field could use an enum to restrict values to valid Kubernetes strategy types
  2. The rollingUpdate object could define expected properties (maxSurge, maxUnavailable) with their types
🔍 Enhanced schema validation
 "updateStrategy": {
     "type": "object",
     "properties": {
         "type": {
             "type": "string",
             "description": "Strategy type",
-            "default": "RollingUpdate"
+            "default": "RollingUpdate",
+            "enum": ["RollingUpdate", "Recreate"]
         },
         "rollingUpdate": {
             "type": "object",
             "description": "Rolling update configuration parameters",
-            "default": {}
+            "default": {},
+            "properties": {
+                "maxSurge": {
+                    "oneOf": [
+                        {"type": "integer", "minimum": 0},
+                        {"type": "string", "pattern": "^[0-9]+%$"}
+                    ],
+                    "description": "Maximum number of pods that can be created over the desired number"
+                },
+                "maxUnavailable": {
+                    "oneOf": [
+                        {"type": "integer", "minimum": 0},
+                        {"type": "string", "pattern": "^[0-9]+%$"}
+                    ],
+                    "description": "Maximum number of pods that can be unavailable during the update"
+                }
+            }
         }
     }
 }

Note: While this enhances validation, Kubernetes itself will validate these fields, so this is a nice-to-have improvement rather than a critical issue.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@charts/openfga/values.schema.json` around lines 33 - 47, The updateStrategy
schema is too loose: tighten validation by making updateStrategy.type an enum
limited to valid Kubernetes strategy values (e.g., "RollingUpdate" and
"Recreate") and define rollingUpdate as an object with explicit properties
maxSurge and maxUnavailable (specify their types as string or integer as
appropriate and add sensible defaults or patterns), ensuring the schema uses
those property names under updateStrategy.rollingUpdate and marks them
optional/required per your chart expectations so consumers get better
validation/documentation.
charts/openfga/values.yaml (2)

3-5: Add documentation comments for the new field.

Other configuration fields in this file include @param style documentation comments explaining their purpose and usage (e.g., lines 63-69 for probe configuration). The updateStrategy field should follow the same pattern to help users understand how to configure it to address the PostgreSQL connection exhaustion issue mentioned in the PR objectives.

📝 Suggested documentation
+## `@param` updateStrategy.type Deployment update strategy type (RollingUpdate or Recreate)
+## `@param` updateStrategy.rollingUpdate Rolling update configuration parameters. Set maxSurge=0 and maxUnavailable=1 to prevent extra pods during updates.
+##
 updateStrategy:
   type: RollingUpdate
   rollingUpdate: {}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@charts/openfga/values.yaml` around lines 3 - 5, The new Kubernetes deployment
field updateStrategy (with nested type: RollingUpdate and rollingUpdate) lacks
the `@param-style` documentation present for other config fields; add short `@param`
comments above updateStrategy describing its purpose, valid values (e.g.,
RollingUpdate, Recreate), how to configure rollingUpdate knobs (e.g.,
maxUnavailable/maxSurge) and mention why adjusting it can mitigate PostgreSQL
connection exhaustion (staggering pod restarts), mirroring the style used for
probe configuration so users know how to tune it.

5-5: Consider documenting that users must configure rollingUpdate parameters to address connection exhaustion.

The default rollingUpdate: {} uses Kubernetes defaults (typically maxSurge=25%, maxUnavailable=25%), which will still create extra pods during updates. To solve the PostgreSQL connection exhaustion problem described in the PR objectives, users need to explicitly set values like:

updateStrategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 0
    maxUnavailable: 1

Consider adding a comment or example in values.yaml showing this configuration pattern.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@charts/openfga/values.yaml` at line 5, Add a short explanatory comment and an
example `updateStrategy` block to values.yaml near the existing `rollingUpdate:
{}` so operators know to set explicit rollingUpdate parameters to avoid
PostgreSQL connection exhaustion; reference the `updateStrategy` and
`rollingUpdate` keys and show the recommended pattern (e.g., `type:
RollingUpdate` with `rollingUpdate.maxSurge: 0` and
`rollingUpdate.maxUnavailable: 1`) so users can copy it into their override
values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@charts/openfga/values.schema.json`:
- Around line 33-47: The updateStrategy schema is too loose: tighten validation
by making updateStrategy.type an enum limited to valid Kubernetes strategy
values (e.g., "RollingUpdate" and "Recreate") and define rollingUpdate as an
object with explicit properties maxSurge and maxUnavailable (specify their types
as string or integer as appropriate and add sensible defaults or patterns),
ensuring the schema uses those property names under updateStrategy.rollingUpdate
and marks them optional/required per your chart expectations so consumers get
better validation/documentation.

In `@charts/openfga/values.yaml`:
- Around line 3-5: The new Kubernetes deployment field updateStrategy (with
nested type: RollingUpdate and rollingUpdate) lacks the `@param-style`
documentation present for other config fields; add short `@param` comments above
updateStrategy describing its purpose, valid values (e.g., RollingUpdate,
Recreate), how to configure rollingUpdate knobs (e.g., maxUnavailable/maxSurge)
and mention why adjusting it can mitigate PostgreSQL connection exhaustion
(staggering pod restarts), mirroring the style used for probe configuration so
users know how to tune it.
- Line 5: Add a short explanatory comment and an example `updateStrategy` block
to values.yaml near the existing `rollingUpdate: {}` so operators know to set
explicit rollingUpdate parameters to avoid PostgreSQL connection exhaustion;
reference the `updateStrategy` and `rollingUpdate` keys and show the recommended
pattern (e.g., `type: RollingUpdate` with `rollingUpdate.maxSurge: 0` and
`rollingUpdate.maxUnavailable: 1`) so users can copy it into their override
values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b78a1553-200f-4d87-9f1f-dedc1cfb21c1

📥 Commits

Reviewing files that changed from the base of the PR and between f4a38ed and 538d899.

📒 Files selected for processing (3)
  • charts/openfga/templates/deployment.yaml
  • charts/openfga/values.schema.json
  • charts/openfga/values.yaml

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Helm chart support for configuring the Kubernetes Deployment spec.strategy so operators can tune rolling upgrade behavior (e.g., maxSurge=0) to avoid temporarily creating extra pods and exhausting shared resources like database connections.

Changes:

  • Introduces a new updateStrategy values entry with a RollingUpdate default.
  • Adds updateStrategy to the chart JSON schema for values validation/discovery.
  • Renders the configured updateStrategy into the Deployment template.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
charts/openfga/values.yaml Adds a new updateStrategy values block with defaults.
charts/openfga/values.schema.json Adds schema entries for updateStrategy.
charts/openfga/templates/deployment.yaml Injects spec.strategy from .Values.updateStrategy.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +12 to +13
{{- if .Values.updateStrategy }}
strategy: {{- toYaml .Values.updateStrategy | nindent 4 }}
Comment on lines +33 to +47
"updateStrategy": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "Strategy type",
"default": "RollingUpdate"
},
"rollingUpdate": {
"type": "object",
"description": "Rolling update configuration parameters",
"default": {}
}
}
},
@@ -1,5 +1,9 @@
replicaCount: 3

Copy link
Copy Markdown
Contributor

@emilic emilic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hebestreit - I think this PR isn't really addressing the root cause here, your DB doesn't have enough connections, sounds like you are right up against your limit. There is already a setting where you can set maxOpenConns. I suggest reducing the amount of connections, you could even use pgbouncer or similar to do connection pooling if you don't want to make any changes.

@hebestreit
Copy link
Copy Markdown
Author

@emilic thanks for your quick reply.

Reducing the maxOpenConns solves the problem but then we can't utilize all available database connections. In this setup the database is a db.t4g.small which has 190 max connections and we're running 3 OpenFGA instances.

We followed the recommendations listed in the Running in Production guide to fine tune the server database settings.

OPENFGA_DATASTORE_MAX_OPEN_CONNS

The server setting OPENFGA_DATASTORE_MAX_OPEN_CONNS should be set to be equal to your database's max connections. For example, in Postgres, you can see this value via running the SQL query SHOW max_connections;. If you are running multiple instances of the OpenFGA server, you should divide this setting equally among the instances. For example, if your database's max_connections is 100, and you have 2 OpenFGA instances, OPENFGA_DATASTORE_MAX_OPEN_CONNS should be set to 50 for each instance.

190 / 3 = ~63 (round to 60)

OPENFGA_DATASTORE_MIN_IDLE_CONNS

OPENFGA_DATASTORE_MIN_IDLE_CONNS: This parameter controls how many connections can remain idle before being closed. As a starting point, set this to around 50–75% of your OPENFGA_DATASTORE_MAX_OPEN_CONNS value to maintain a stable connection pool and avoid the overhead of frequently recreating connections, then adjust based on observed connection churn and database load.

60 * 0.75 = 45

OPENFGA_DATASTORE_MIN_OPEN_CONNS

OPENFGA_DATASTORE_MIN_OPEN_CONNS: This parameter should be the minimum number of database connections you want to maintain. This helps ensure that a baseline pool of connections is always available. As a starting point, consider setting this to a small, fixed baseline (for example between 5 and 20 connections), or roughly 10–30% of the maximum connections your PostgreSQL instance allows, while ensuring it does not exceed that database limit. If you are running multiple instances of the OpenFGA server, you should divide this setting equally among the instances.

Needs to set same as OPENFGA_DATASTORE_MIN_IDLE_CONNS otherwise you get the error datastore MinOpenConns must not be less than datastore MinIdleConns.

Configuration

We end up with below configuration:

replicaCount: 3

extraEnvVars:
  - name: OPENFGA_DATASTORE_MAX_OPEN_CONNS
    value: "60"
  - name: OPENFGA_DATASTORE_MIN_IDLE_CONNS
    value: "45"
  - name: OPENFGA_DATASTORE_MIN_OPEN_CONNS
    value: "45"

@hebestreit
Copy link
Copy Markdown
Author

@emilic is there anything we need to configure differently or can we merge this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants