Skip to content

fix(seaweedfs): configure postgres2 connection pool for the filer - #2906

Merged
Aleksei Sviridkin (lexfrei) merged 1 commit into
cozystack:mainfrom
mattia-eleuteri:fix/seaweedfs-postgres2-connection-pool
Jul 3, 2026
Merged

Aleksei Sviridkin (lexfrei) merged 1 commit into
cozystack:mainfrom
mattia-eleuteri:fix/seaweedfs-postgres2-connection-pool

Conversation

@mattia-eleuteri

@mattia-eleuteri mattia-eleuteri commented Jun 12, 2026 •

Copy link
Copy Markdown
Collaborator

What this PR does

  • Adds WEED_POSTGRES2_CONNECTION_MAX_IDLE=20, WEED_POSTGRES2_CONNECTION_MAX_OPEN=40 and WEED_POSTGRES2_CONNECTION_MAX_LIFETIME_SECONDS=600 to the filer extraEnvironmentVars in packages/system/seaweedfs/values.yaml.

The vendored seaweedfs chart only ships connection pool settings for the mysql store (WEED_MYSQL_CONNECTION_MAX_*), which cozystack does not use. The postgres2 store, which cozystack enables, has no pool settings at all. As a result the Go database/sql pool runs with SetMaxIdleConns(0): every filer metadata lookup opens a fresh PostgreSQL connection (TCP + TLS + SCRAM, ~300 ms each). With ~5 path-component lookups per S3 operation, this adds roughly 2 seconds of latency to every S3 request, even on an idle cluster.

Measurements (production cluster, 12 nodes, 2 filers, CNPG backend)

Before / after applying these three variables, same test (sequential ops through the S3 gateway):

Operation Before After
PUT 4 KiB (p50) 10.0 s 0.28 s
GET 4 KiB (p50) 3.0 s 0.14 s
HEAD (p50) 2.6 s 0.16 s
Bounded LIST, 100 keys (p50) 3.8 s 0.37 s

pg_stat_activity confirmed the root cause: before the fix every backend was younger than ~200 ms (permanent connection churn); after the fix connections are reused for minutes. Real-traffic p95 of SeaweedFS_filerStore_request_seconds dropped from 1.3–6.5 s to ~0.18 s.

max_open is capped at 40 so that the default two filer replicas stay below the CNPG default max_connections of 100.

Release note

fix(seaweedfs): configure postgres2 connection pool for the filer, removing ~2s of per-request S3 latency caused by PostgreSQL connection churn

Summary by CodeRabbit

  • Chores
    • Optimized PostgreSQL connection pool configuration in SeaweedFS to reduce latency and improve performance during metadata operations.

@github-actions github-actions Bot added area/storage Issues or PRs related to storage (linstor, seaweedfs, bucket, velero, harbor) kind/bug Categorizes issue or PR as related to a bug size/XS This PR changes 0-9 lines, ignoring generated files labels Jun 12, 2026
@coderabbitai

coderabbitai Bot commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

SeaweedFS filer configuration is updated with PostgreSQL connection pool tuning parameters: WEED_POSTGRES2_CONNECTION_MAX_IDLE, WEED_POSTGRES2_CONNECTION_MAX_OPEN, and WEED_POSTGRES2_CONNECTION_MAX_LIFETIME_SECONDS, accompanied by explanatory comments about reducing latency.

Changes

SeaweedFS PostgreSQL Connection Pool Tuning

Layer / File(s) Summary
PostgreSQL connection pool environment variables
packages/system/seaweedfs/values.yaml
Three PostgreSQL connection pooling parameters are added to the filer's extraEnvironmentVars configuration with inline comments explaining their purpose and referencing database max-connection constraints to reduce latency from frequently opened connections across filer metadata lookups.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

Poem

🐰 A pool of connections, so carefully tuned,
SeaweedFS filer now freed from its gloom.
Less latency blooms when the database rests,
Connection pooling passes all tests! 🚀

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: configuring PostgreSQL connection pool settings for SeaweedFS filer, which directly corresponds to the core purpose of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a performance bottleneck in the SeaweedFS filer configuration when using a PostgreSQL backend. By default, the Go database/sql pool was not maintaining idle connections, resulting in a new connection being established for every metadata lookup. The changes introduce explicit environment variables to manage the connection pool, ensuring connections are reused and significantly improving the responsiveness of S3 operations.

Highlights

  • PostgreSQL Connection Pooling: Added explicit connection pool settings (max idle, max open, and max lifetime) for the SeaweedFS filer using the postgres2 store.
  • Performance Impact: Resolved significant latency issues caused by PostgreSQL connection churn, reducing per-request S3 latency by approximately 2 seconds.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment Gemini (@gemini-code-assist) Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/system/seaweedfs/values.yaml`:
- Around line 52-54: Values WEED_POSTGRES2_CONNECTION_MAX_IDLE,
WEED_POSTGRES2_CONNECTION_MAX_OPEN, and
WEED_POSTGRES2_CONNECTION_MAX_LIFETIME_SECONDS are defined but the vendored Helm
chart under packages/system/seaweedfs/charts does not wire them into the
container environment; update the chart templates (the Deployment/StatefulSet
env section) to read these values and emit corresponding env vars (or map them
via value keys like postgresql/postgres2.* if the chart uses nested names),
e.g., add env entries that reference .Values.WEED_POSTGRES2_CONNECTION_MAX_IDLE,
.Values.WEED_POSTGRES2_CONNECTION_MAX_OPEN, and
.Values.WEED_POSTGRES2_CONNECTION_MAX_LIFETIME_SECONDS (or add passthrough
values in the chart’s values.yaml) so the SeaweedFS container actually receives
those WEED_POSTGRES2_* environment variables.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5f0b807e-1ddb-49a0-8478-eb75acd181ae

📥 Commits

Reviewing files that changed from the base of the PR and between 25a6b56 and a4c9a85.

📒 Files selected for processing (1)
  • packages/system/seaweedfs/values.yaml

Comment on lines +52 to +54
WEED_POSTGRES2_CONNECTION_MAX_IDLE: "20"
WEED_POSTGRES2_CONNECTION_MAX_OPEN: "40"
WEED_POSTGRES2_CONNECTION_MAX_LIFETIME_SECONDS: "600"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

SeaweedFS WEED_POSTGRES2_CONNECTION_MAX_IDLE WEED_POSTGRES2_CONNECTION_MAX_OPEN environment variables documentation

💡 Result:

In SeaweedFS, configuration options—including database connection pool settings—are typically defined in the filer configuration file (e.g., filer.toml) and can be overridden by environment variables [1]. For the PostgreSQL filer store, while standard documentation identifies variables like WEED_POSTGRES_CONNECTION_MAX_IDLE and WEED_POSTGRES_CONNECTION_MAX_OPEN [2], the specific variable names for the second PostgreSQL instance (often configured under a [postgres2] section in the configuration file) follow the same pattern by replacing the section prefix [3][4]. Based on the mapping logic used in SeaweedFS, the environment variables for the secondary PostgreSQL store are: WEED_POSTGRES2_CONNECTION_MAX_IDLE WEED_POSTGRES2_CONNECTION_MAX_OPEN These variables correspond to the configuration keys connection_max_idle and connection_max_open within the [postgres2] section of your configuration file. When set, they control the connection pool size for the secondary PostgreSQL database instance used by the SeaweedFS filer [3]. If you are setting these via environment variables, ensure the prefix matches the exact section name defined in your configuration file, as the system maps these by replacing the dot in configuration paths with an underscore [1]. You may also want to set WEED_POSTGRES2_CONNECTION_MAX_LIFETIME_SECONDS to manage the lifetime of these connections [5][3].

Citations:


🏁 Script executed:

#!/bin/bash
# Description: Search for Postgres2 connection pool environment variable usage in SeaweedFS chart and verify naming

# Check if the vendored chart references any Postgres2 connection pool settings
echo "=== Checking vendored chart for Postgres2 pool settings ==="
fd -t f . packages/system/seaweedfs/charts/ --exec rg -l 'POSTGRES2.*CONNECTION' {}

# Search for any existing Postgres2 environment variable patterns to confirm naming convention
echo -e "\n=== Existing WEED_POSTGRES2 environment variables in values.yaml ==="
rg -n 'WEED_POSTGRES2_' packages/system/seaweedfs/values.yaml

Repository: cozystack/cozystack

Length of output: 571


SeaweedFS env var names match; Helm may not be wiring them

The SeaweedFS Postgres2 connection pool env var names used here (WEED_POSTGRES2_CONNECTION_MAX_IDLE, WEED_POSTGRES2_CONNECTION_MAX_OPEN, WEED_POSTGRES2_CONNECTION_MAX_LIFETIME_SECONDS) align with SeaweedFS’s [postgres2] configuration-to-environment mapping (replacing the section prefix with WEED_ + POSTGRES2_).

Main remaining risk: the vendored SeaweedFS Helm chart under packages/system/seaweedfs/charts/ didn’t reference any Postgres2 connection settings (no POSTGRES2.*CONNECTION hits), so these values may not actually be rendered into the SeaweedFS container environment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/system/seaweedfs/values.yaml` around lines 52 - 54, Values
WEED_POSTGRES2_CONNECTION_MAX_IDLE, WEED_POSTGRES2_CONNECTION_MAX_OPEN, and
WEED_POSTGRES2_CONNECTION_MAX_LIFETIME_SECONDS are defined but the vendored Helm
chart under packages/system/seaweedfs/charts does not wire them into the
container environment; update the chart templates (the Deployment/StatefulSet
env section) to read these values and emit corresponding env vars (or map them
via value keys like postgresql/postgres2.* if the chart uses nested names),
e.g., add env entries that reference .Values.WEED_POSTGRES2_CONNECTION_MAX_IDLE,
.Values.WEED_POSTGRES2_CONNECTION_MAX_OPEN, and
.Values.WEED_POSTGRES2_CONNECTION_MAX_LIFETIME_SECONDS (or add passthrough
values in the chart’s values.yaml) so the SeaweedFS container actually receives
those WEED_POSTGRES2_* environment variables.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request configures connection pool settings for SeaweedFS's PostgreSQL metadata store in packages/system/seaweedfs/values.yaml. Specifically, it sets WEED_POSTGRES2_CONNECTION_MAX_IDLE to 20, WEED_POSTGRES2_CONNECTION_MAX_OPEN to 40, and WEED_POSTGRES2_CONNECTION_MAX_LIFETIME_SECONDS to 600. These settings prevent the Go SQL pool from keeping zero idle connections, which previously caused a fresh connection to be opened for every filer metadata lookup and introduced significant latency to S3 operations. I have no feedback to provide as there are no review comments to assess.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@dosubot dosubot Bot added the kind/backport Categorizes issue or PR as requiring a backport to the current release line label Jun 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The change is correct and the env vars are wired: filer.extraEnvironmentVars flows through the seaweedfs.mergeExtraEnvironmentVars helper into the filer StatefulSet env block (filer-statefulset.yaml, lines 118-129), so WEED_POSTGRES2_CONNECTION_MAX_IDLE/OPEN/LIFETIME_SECONDS land in the container — the earlier bot comment about them not reaching the container does not hold. The WEED_<SECTION>_<KEY> naming matches how seaweedfs maps env vars to store config and mirrors the existing WEED_MYSQL_CONNECTION_MAX_* keys. Capping max_open at 40 against a two-replica filer default keeps total connections under the CNPG default of 100, and the inline comment usefully flags that constraint for anyone scaling filer.replicas. LGTM.

Non-blocking: a small helm-unittest asserting these keys appear in the filer env would lock in the behavior and pre-empt the "not wired" confusion, but it's not required to merge.

The vendored seaweedfs chart ships connection pool settings only for the
mysql store, which cozystack does not use. The postgres2 store, which is
enabled, has no pool settings, so the Go sql pool keeps zero idle
connections and every filer metadata lookup opens a fresh PostgreSQL
connection (TCP + TLS + SCRAM, ~300ms each). With ~5 path lookups per S3
operation this adds roughly 2 seconds of latency to every S3 request,
regardless of cluster load.

Measured on a production cluster (12 nodes, 2 filers): PUT of a 4KiB
object went from 10s (p50) to 0.28s, HEAD from 2.6s to 0.16s after
setting these values; pg_stat_activity confirmed connections were
previously recycled every ~200ms and are now reused.

max_open is capped at 40 so that two filer replicas stay below the CNPG
default max_connections of 100.

Signed-off-by: mattia-eleuteri <[email protected]>
@lexfrei
Aleksei Sviridkin (lexfrei) force-pushed the fix/seaweedfs-postgres2-connection-pool branch from a4c9a85 to 49cbea8 Compare July 3, 2026 16:14
@lexfrei
Aleksei Sviridkin (lexfrei) merged commit 901bb98 into cozystack:main Jul 3, 2026
13 of 15 checks passed
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

Successfully created backport PR for release-1.5:

myasnikovdaniil added a commit that referenced this pull request Jul 6, 2026
… pool for the filer (#3194)

# Description
Backport of #2906 to `release-1.5`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/storage Issues or PRs related to storage (linstor, seaweedfs, bucket, velero, harbor) kind/backport Categorizes issue or PR as requiring a backport to the current release line kind/bug Categorizes issue or PR as related to a bug size/XS This PR changes 0-9 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants