Skip to content

feat: save bandwidth for clients - #395

Merged
konsalex merged 1 commit into
mainfrom
bandwidth-savings
Oct 11, 2026
Merged

konsalex merged 1 commit into
mainfrom
bandwidth-savings

Conversation

@konsalex

@konsalex konsalex commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

We had some excess egress, that we need to fix to reduce billing 👀

This PR is reading less of the users row on the endpoints the desktop app polls.

The app polls /teammates, /calls/presence and /user every 10 to 30 seconds. Every one of those requests loaded the full user row prior to this change, including social_metadata (about 1.3KB, I validated withpg_stat_statements_info historical data) and hashed_password. Also GetTeammates re-fetched the current user and their team on every call.

To optimize, which should drop the egress quite a lot below are the changes. Also ideally we would go to a websocket/event driven approach, but its quite a refactor for now:

  1. Read-only auth lookups now select only the UserProfile columns. That covers the auth helper, the websocket handshake, teammates and presence. /user, onboarding and the Linux waitlist still load the full row because they need the JSON columns.
  2. GetTeammates no longer re-fetches the current user, and it selects only profile columns for teammates.
  3. UpdateName and ChangeTeam write only the columns they change instead of saving the whole row.
  4. The access check for calls loads just the team and its subscription, through a new TeamAccess struct.
  5. The Postgres connection pool settings are now hardcoded: 10 open and 10 idle connections, a 30 minute max lifetime and a 10 minute idle timeout. The default was 2 idle connections, and the backend kept reconnecting. That was a drive-by fix. This was also visible in pg_stat_statements as repeated pgbouncer.get_auth and DISCARD ALL queries.
  6. This also changes two small behaviors. The teammates response no longer includes each teammate's unsubscribe_id, and RemoveTeammate returns 500 instead of 400 when the database fails (also drive-by).

Super rough estimate, database traffic per polled request drops from about 4.25KB avg to 1.5KB avg, which takes us from around 15GB to around 5GB of egress a month.

@netlify

netlify Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for hoppdocs ready!

Name Link
🔨 Latest commit 25817ca
🔍 Latest deploy log https://app.netlify.com/projects/hoppdocs/deploys/6ac6a6e1e6e3720008f9be33
😎 Deploy Preview https://deploy-preview-395--hoppdocs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 01aea676-1323-4dce-9516-855fadac5eae
📥 Commits

Reviewing files that changed from the base of the PR and between c35ef27 and 25817ca.

📒 Files selected for processing (7)
  • backend/internal/handlers/handlers.go
  • backend/internal/handlers/slackHandlers.go
  • backend/internal/handlers/utils.go
  • backend/internal/handlers/websocketHandlers.go
  • backend/internal/models/user.go
  • backend/internal/server/server.go
  • backend/test/integration/integration_test.go

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

The change separates core user profile data from user-specific fields, updates authentication and handlers to use profile or full-user records, centralizes team-access calculation, and configures PostgreSQL connection-pool settings.

Changes

User profile and access flows

Layer / File(s) Summary
Profile model and construction
backend/internal/models/user.go, backend/internal/handlers/handlers.go, backend/test/integration/integration_test.go
User embeds UserProfile. Profile queries and methods return or use profiles, and signup and test-user construction initialize profile fields through the embedded type.
Team access calculation
backend/internal/models/user.go, backend/internal/handlers/utils.go
TeamAccess represents Pro and trial access. GetTeamAccess calculates access, and checkUserHasAccess evaluates it for a profile’s team.
Profile authentication and call integrations
backend/internal/handlers/utils.go, backend/internal/handlers/websocketHandlers.go, backend/internal/handlers/slackHandlers.go, backend/internal/handlers/handlers.go
Authentication helpers distinguish profile lookup from full-user lookup. WebSocket calls, Slack participant helpers, and LiveKit token generation use UserProfile where applicable.
Full-user operations and targeted updates
backend/internal/handlers/handlers.go
Handlers load full user records for operations that need fields outside the profile. Name and team changes update targeted columns. Teammate removal loads the team separately, and room creation no longer assigns the user’s Team association.

Database connection setup

Layer / File(s) Summary
Database opening and PostgreSQL pool settings
backend/internal/server/server.go
SQLite and PostgreSQL opening errors are handled in their respective branches. PostgreSQL setup configures open and idle connection limits, maximum connection lifetime, and maximum idle time.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Refactor

Suggested reviewers: iparaskev

Merge Risk: ⚪ Minimal · up to 25817

No demonstrated regression remains that should block merging after normal checks.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 7 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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.
Title check ✅ Passed The title describes the primary objective of reducing client bandwidth usage through slimmer user data and profile-based authentication changes.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@konsalex
konsalex merged commit 855bff1 into main Oct 11, 2026
18 checks passed
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.

2 participants