iachat/app
Vishnu Narayanan 462ab5241c
perf: fix notifications duplicate query and add composite index (#12110)
Database CPU utilization was spiking due to expensive notification COUNT
queries. Analysis revealed two critical issues:

1. Missing database index: Notification count queries were performing
table scans without proper indexing
2. Duplicate WHERE clauses: SQL queries contained redundant read_at IS
NULL conditions, causing unnecessary query complexity

 ### Root Cause Analysis

  The expensive queries were:
```
  -- 41.61 calls/sec with duplicate condition
  SELECT COUNT(*) FROM "notifications"
  WHERE "notifications"."user_id" = $1
    AND "notifications"."account_id" = $2
    AND "notifications"."snoozed_until" IS NULL
    AND "notifications"."read_at" IS NULL
    AND "notifications"."read_at" IS NULL  -- Duplicate!
```
This was caused by a logic error in NotificationFinder#unread_count
introduced in commit cd06b2b33 (PR #8907). The method assumed
@notifications contained all notifications, but @notifications was
already filtered to unread notifications in most cases.

###  The Default Query Flow:

1. Frontend calls: NotificationsAPI.getUnreadCount() →
/notifications/unread_count
  2. No parameters sent, so params = {}
  3. NotificationFinder setup:
    - find_all_notifications: WHERE user_id = ? AND account_id = ?
    - filter_snoozed_notifications: WHERE snoozed_until IS NULL
- filter_read_notifications: WHERE read_at IS NULL (because
type_included?('read') is false)
  4. unread_count called: Adds another WHERE read_at IS NULL
----
### Solution

  1. Added Missing Database Index
  - Index: (user_id, account_id, snoozed_until, read_at)
  2. Fixed Duplicate WHERE Clause Logic
2025-08-07 15:59:40 +05:30
..
actions fix: Disable enqueueing Avatar jobs if the URL is invalid (#12035) 2025-07-24 12:56:39 +04:00
assets feat: Hide installation identifier (#11722) 2025-06-17 15:45:40 -07:00
builders fix: missing metrics and labels from label summary (#11718) 2025-06-12 17:58:56 +05:30
channels fix: Move contact events to account stream rather than individual user stream (#11082) 2025-03-13 17:46:48 -07:00
controllers feat: Integrate Twilio WhatsApp ProfileName for contact name resolution (#12122) 2025-08-07 12:53:39 +05:30
dashboards chore: improve plan-based feature handling with plan hierarchy (#11335) 2025-04-28 14:13:56 -07:00
dispatchers feat(ee): Add Captain features (#10665) 2025-01-14 16:15:47 -08:00
drops feat: Add the support for custom attributes in message variables (#8511) 2023-12-08 14:13:35 -08:00
fields chore: improve plan-based feature handling with plan hierarchy (#11335) 2025-04-28 14:13:56 -07:00
finders perf: fix notifications duplicate query and add composite index (#12110) 2025-08-07 15:59:40 +05:30
helpers chore: Add submenu for super admin settings (#11860) 2025-07-15 21:28:39 -07:00
javascript chore: Replace Thumbnail with Avatar in conversation card (#12112) 2025-08-07 09:50:24 +05:30
jobs fix: Disable IMAP inboxes that requires authorization (#12092) 2025-08-01 16:32:29 -07:00
listeners fix: Disable automations on auto-reply emails (#12101) 2025-08-05 13:17:06 +05:30
mailboxes fix: Disable automations on auto-reply emails (#12101) 2025-08-05 13:17:06 +05:30
mailers fix: footer in ssl_instructions email (#12076) 2025-07-31 11:44:17 -07:00
models fix: Disable automations on auto-reply emails (#12101) 2025-08-05 13:17:06 +05:30
policies feat(cloud): Add support for viewing status of SSL in custom domains (#12011) 2025-07-30 10:52:47 -07:00
presenters fix: Disable automations on auto-reply emails (#12101) 2025-08-05 13:17:06 +05:30
services feat: Integrate Twilio WhatsApp ProfileName for contact name resolution (#12122) 2025-08-07 12:53:39 +05:30
views feat(cloud): Add support for viewing status of SSL in custom domains (#12011) 2025-07-30 10:52:47 -07:00
workers feat: API Endpoints to update message status (#11387) 2025-04-29 15:33:11 -07:00