From f16c7e59b8f2ed7996768f0d1ee47917bc982701 Mon Sep 17 00:00:00 2001 From: Vishnu Narayanan Date: Tue, 17 Feb 2026 18:40:36 +0530 Subject: [PATCH] perf: use update_columns for contact last_activity_at MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace `sender.update(last_activity_at:)` with `update_columns` in Message#update_contact_activity. This runs on every incoming message (3.3M calls/day) and the full ActiveRecord update lifecycle is unnecessary for a single timestamp write: - Skips before_save :sync_contact_attributes (only relevant for email/phone/identifier changes, not last_activity_at) - Skips after_update_commit :dispatch_update_event which fires CONTACT_UPDATED → ActionCable broadcasts, webhook deliveries, and LeadSquared hooks on every incoming message with no meaningful data change - Eliminates 192K seconds/day of DB time from contact UPDATEs that trigger full validation and callback chains --- app/models/message.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/message.rb b/app/models/message.rb index 20b9a756d..1736df978 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -318,7 +318,9 @@ class Message < ApplicationRecord end def update_contact_activity - sender.update(last_activity_at: DateTime.now) if sender.is_a?(Contact) + # rubocop:disable Rails/SkipsModelValidations + sender.update_columns(last_activity_at: DateTime.now) if sender.is_a?(Contact) + # rubocop:enable Rails/SkipsModelValidations end def update_waiting_since