DEV Community

Suganth
Suganth

Posted on

How We Saved Money and Prevented "Ghost" Messages by Respecting Telecom Quiet Hours

Building an automated marketing platform comes with technical challenges.

But sometimes, the biggest challenges aren't technical. They are regulatory.

At Casa Retail AI, we built a robust journey module that targets specific customer cohorts and executes actions, like sending SMS or RCS messages, automatically.

But in India, you can't just text customers whenever you want.

Here is how we implemented a "Quiet Hours" deferral system to comply with telecom laws, save costs, and ensure zero dropped messages.


The Context: India's TRAI Regulations

India's Telecom Regulatory Authority of India (TRAI) enforces strict guidelines for commercial communications.

One of the most important rules is the "Quiet Hours" restriction.

To protect consumers from spam and disturbances, TRAI mandates that promotional SMS and RCS messages cannot be sent between 9:00 PM and 9:00 AM.

This is an important distinction. TRAI quiet hours apply only to promotional messages — re-engagement offers, discount campaigns, win-back journeys, and the like. Transactional messages, such as OTPs, order confirmations, and service alerts, are exempt and can be delivered 24/7.

Our journey module at Casa is purpose-built for marketing automations — targeting customer cohorts and triggering re-engagement actions. This puts every SMS and RCS event we fire squarely in the promotional category.

If one of these journeys triggers at 11:30 PM, the telecom provider will intercept and drop the message.


The Problem: Failed Messages and Hidden Costs

When a promotional journey triggers during quiet hours, the message gets blocked at the telecom provider level.

But this surfaced two serious problems for our tenants (retailers):

  1. The Cost Problem: Some third-party message providers charge the tenant for the API request attempt, even when the message is rejected due to TRAI restrictions. The retailer was being billed for a message their customer never received.
  2. The "Ghosting" Problem: The retailer intended to send a promotional offer — a re-engagement discount or a win-back campaign. Because the message failed silently at the provider level, the customer never received the offer, and that marketing touchpoint was permanently lost.

This is unique to promotional use cases. A transactional OTP or a shipping alert can wait for nothing — it needs to arrive immediately. But a promotional campaign triggered at 11 PM has a natural next-day intent: reach the customer when they are awake.

We needed a system that intercepted these promotional messages before they reached the provider, held them safely overnight, and sent them when it was legal to do so.


The Solution: The Deferral Queue

We introduced a strict time-window check right before message dispatch.

If a message attempts to fire outside of the 9 AM - 9 PM window, we halt the dispatch.

Instead of dropping the message or paying for a failed API call, we push the payload into a separate Kafka log to deferred-sms | deferred-rcs.

The next morning at exactly 9:00 AM, a scheduled worker sweeps these deferred queues and posts the messages back into the primary processing queue.

To give our tenants flexibility, we made this deferral behavior entirely configurable. Tenants can opt-in to deferral or choose to simply drop the messages if time-sensitivity is critical.

Finally, every deferred action is logged into ClickHouse. This provides our analytics engine full visibility into how many messages were deferred, allowing tenants to see exactly how their campaigns behave outside of business hours.


How it works:

  1. Timezone Awareness: We strictly enforce the Asia/Kolkata time zone, meaning our platform can be hosted anywhere globally but will always respect Indian local time rules.
  2. Redis Caching: Configuration reads are cached in Redis for one hour. Since journey engines process thousands of messages per second, hitting PostgreSQL for every message was out of the question.

The Business Impact

This small compliance feature transformed how we pitch our platform's reliability.

We can now promise our tenants two things:

  1. No "Ghost" Messages: If a customer qualifies for a campaign at midnight, they will receive the message at 9 AM the next morning.
  2. No Wasted Costs: Tenants no longer pay external API providers for messages that were guaranteed to fail at the telecom level.

The integration with ClickHouse means that tenants can visualize exactly how much money the deferral queue saved them, building trust in our platform's intelligence.


What I Learned

Regulatory constraints are not edge cases to route around — they are business rules to design for.

The natural instinct is to handle a compliance failure at the point of failure: catch the error, log it, move on. But that approach treats the regulation as an exception rather than a known, predictable constraint.

When we modeled TRAI quiet hours as a first-class concern — one with its own deferral pipeline, its own configuration surface, and its own audit trail in ClickHouse — the system became genuinely more reliable for our tenants.

Compliance and product quality are not in tension. Handled correctly, they reinforce each other.

Top comments (0)