Skip to content

Repository files navigation

Namma Push Engine Logo

Namma Push Engine

Made with ❀️ by blacklovertech

Namma Push Engine is a lightning-fast, ultra-optimized, gRPC-based push-notification service written in Rust. It acts as a real-time bridge between your backend services and client apps like driver/rider apps, dashboards, and live tracking views β€” with zero-HTTP authentication via Redis sessions.


⚑ Features

Feature Description
πŸ¦€ Pure Rust Performance Built on tokio + tonic. Handles 100,000+ persistent bi-directional gRPC streams on a single server.
⏱️ Ultra-Low Latency P50 < 10ms · P95 < 25ms · P99 < 50ms at 50,000 TPS
🎯 Dirty-Bit Polling Epoll-style adaptive polling β€” only scans streams with unread messages. Near-zero Redis I/O at idle.
πŸ” Redis Session Auth Sub-millisecond auth via shared Redis session store. Zero external HTTP calls on connect.
πŸ”” FCM Fallback Automatically fires Firebase Cloud Messaging when a client is offline or the app is killed.
♻️ Zero GC Pauses No garbage collector β€” eliminates the tail-latency spikes that plague Node.js and Go at scale.

πŸ”„ Full System Flow

sequenceDiagram
    autonumber
    actor User as πŸ‘€ User (Mobile App)
    participant Backend as πŸ–₯️ Your Backend
    participant Redis as πŸ—„οΈ Redis
    participant Engine as πŸš€ Namma Push Engine

    Note over Backend,Redis: Phase 1 β€” Authentication Setup
    Backend->>Redis: SET NS:{token} {driverId} EX 86400
    Redis-->>Backend: βœ… OK (Session stored, TTL 24h)

    Note over User,Engine: Phase 2 β€” Client Connection
    User->>Engine: gRPC stream open (header: token={token})
    Engine->>Redis: GET NS:{token}
    Redis-->>Engine: {driverId}
    Engine-->>User: βœ… Auth OK β€” stream is LIVE

    Note over Backend,Engine: Phase 3 β€” Notification Delivery
    Backend->>Redis: XADD N{driverId}{shard} * [id, title, body, entity...]
    Redis-->>Backend: βœ… Stream entry ID

    loop Every poll cycle (dirty-bit tracking)
        Engine->>Redis: XREAD N{driverId}{0..N_SHARDS}
        Redis-->>Engine: Notification entries
        Engine-->>User: πŸ“¨ Push via open gRPC stream
    end

    Note over User,Engine: Phase 4 β€” Acknowledgement or Fallback
    alt User ACKs notification
        User->>Engine: ACK (notification_id)
        Engine->>Redis: XDEL N{driverId}{shard} {entry_id}
    else Client offline / timeout
        Engine->>Backend: πŸ”” FCM Push via Firebase API
    end
Loading

πŸ” Redis Session Authentication

Namma Push Engine uses a shared Redis session store for authentication β€” no extra auth service required.

flowchart LR
    A([πŸ–₯️ Backend]) -- "SET NS:&lbrace;token&rbrace; &lbrace;driverId&rbrace; EX 86400" --> R[(πŸ—„οΈ Redis)]
    U([πŸ“± Mobile App]) -- "gRPC connect\ntoken=&lbrace;token&rbrace;" --> E([πŸš€ Push Engine])
    E -- "GET NS:&lbrace;token&rbrace;" --> R
    R -- "&lbrace;driverId&rbrace; βœ…" --> E
    E -- "Stream LIVE" --> U
Loading

Why Redis Auth Is Faster

Method Latency Extra Service
❌ HTTP Auth API 30 – 100ms per connect Requires auth microservice
βœ… Redis Session < 1ms per connect None β€” Redis is already there

Session Lifecycle

stateDiagram-v2
    [*] --> Active : Backend sets NS:&lbrace;token&rbrace;
    Active --> Connected : App connects (GET succeeds)
    Connected --> Active : App disconnects (key still valid)
    Active --> Expired : TTL reaches 0 (auto-cleanup)
    Active --> Revoked : Backend DEL NS:&lbrace;token&rbrace; (ban/logout)
    Expired --> [*]
    Revoked --> [*]
Loading

Key Format Reference

Redis Key Value TTL Purpose
NS:{token} {driverId} 24h (backend-set) Session auth lookup
N{driverId}{shard} Stream entries Notification TTL Delivery stream
active-notification PubSub messages β€” Dirty-bit signal channel

βš™οΈ Configuration (notification_service.dhall)

let redis_cfg = {
    host     = "0.0.0.0",   -- Redis host
    port     = 30001,        -- Redis port
    partition = 0,           -- DB index (sessions use NS: prefix on same DB)
    pool_size = 50,          -- Connection pool size
    ...
}

in {
    grpc_port   = 50051,    -- Mobile apps connect here
    max_shards  = +5,       -- Stream shards per client (parallelism)
    redis_cfg   = redis_cfg,
    fcm_cfg     = { api_key = "...", enabled = True },
    ...
}

Full Parameter Reference

Parameter Type Default Description
grpc_port Integer 50051 gRPC server port (mobile apps connect here)
http_server_port Integer 9091 Health check + Prometheus /metrics endpoint
redis_cfg Object β€” host, port, pool_size, partition, cluster support
fcm_cfg Object β€” Firebase key + enabled flag for offline fallback
logger_cfg Object INFO Log verbosity: TRACE / DEBUG / INFO / WARN / ERROR
max_shards Integer 5 Redis stream shards per client β€” higher = more parallelism
channel_buffer Integer 100000 Internal mpsc channel capacity for PubSub events
request_timeout_seconds Integer 60 Drop unresponsive clients after N seconds
retry_delay_millis Integer 1000 Re-send interval for unacknowledged notifications
expired_cleanup_delay_millis Integer 500 GC interval to clear TTL-expired stream entries
read_all_connected_client_notifications Boolean False Backfill all active clients on startup

πŸš€ Running the Engine

Docker Compose (Recommended)

docker-compose up --build -d

This starts Redis and builds the canonical Dockerfile.release image for the Namma Push Engine gateway. The Compose service passes REDIS_HOST=redis and REDIS_PORT=6379 so the container can resolve the Compose Redis service by name.

Manual Build

cd crates/notification_service
cargo run --release

πŸ§ͺ Test with Mock Sender

cd mock-sender
npm install
npm run start

The mock sender automatically:

  1. Injects Redis sessions (NS:{token}) for all configured test clients
  2. Pushes a test notification to every shard of each client's stream (N{clientId}{shard})
  3. Your connected node-client receives it instantly via the live gRPC stream

πŸ“Š Metrics & Observability

Prometheus metrics are auto-exported at:

http://<your-server-ip>:9091/metrics

Point Grafana to this endpoint to monitor the following exported Prometheus metrics:

Counters

  • total_notifications: Total number of notifications processed (labeled by category)
  • delivered_notifications: Total successfully delivered to clients over gRPC
  • retried_notifications: Total notifications queued for retry
  • expired_notifications: Total notifications that expired (TTL exceeded)
  • cleanup_push_skipped: Stream cleanup executions that were skipped

Gauges

  • connected_clients: Current number of active gRPC streams (live clients)

Histograms

  • notification_latency: Latency of notification delivery (P50/P95/P99)
  • notification_client_connection_duration: Duration of client connections
  • measure_duration: Core loop and critical section processing duration
  • call_external_api: External FCM / Auth API call latencies
  • termination: Graceful shutdown durations
  • incoming_api: gRPC request processing latencies
  • channel_delay: Internal mpsc channel delays and PubSub message latencies

Notification-Only Responsibility

Namma Push Engine is intentionally focused on high-frequency notification delivery. It authenticates gRPC streams, reads Redis Streams, delivers notifications, processes notification acknowledgements, retries unacknowledged entries, cleans up expired entries, and optionally uses FCM fallback.

Business actions such as accepting a ride, accepting an order, payment, trading, inventory, or emergency dispatch should call the responsible backend domain API directly. This service does not expose a business-action webhook or execute business Lua workflows.

Backend β†’ Redis Stream β†’ Rust notification service β†’ gRPC mobile stream
Mobile ACK β†’ Rust service β†’ retry state and Redis cleanup
Mobile business action β†’ backend domain API

Keeping the business workflow in the backend makes this service smaller, easier to reuse, and easier to scale for high-frequency notification traffic.

What Applications Can Build With Namma Push

Namma Push is designed as a reusable notification foundation for applications that need reliable, low-latency communication with connected mobile, web, or worker clients. A gig partner can use it for driver dispatch alerts, rider updates, delivery status changes, support messages, shift reminders, safety alerts, and operational announcements without embedding domain logic into the notification service.

The same foundation can support food delivery, logistics, field service, healthcare dispatch, fleet operations, commerce, live dashboards, incident response, and internal workforce tools. Each partner keeps its own backend rules and database while using the same notification transport, Redis delivery model, gRPC client connection, acknowledgement behavior, retry policy, and observability conventions.

Application capability How Namma Push helps
Worker or driver dispatch Delivers nearby job, pickup, cancellation, or reassignment notifications to connected worker apps.
Order and delivery updates Sends state changes such as placed, packed, picked up, delayed, or completed.
Live operations dashboards Streams low-latency status notifications to web dashboards and control rooms.
Safety and emergency alerts Uses immediate gRPC delivery with retry and optional FCM fallback when the app is offline.
Workforce communication Sends shift, schedule, policy, and operational messages with notification IDs for acknowledgement.
Multi-application platforms Allows several products to share the same notification infrastructure while keeping tenant and domain rules in their own backends.

Reusable integration contract

A partner application needs only a small integration layer in its backend. It creates or refreshes a Redis session for the client, writes a notification entry to the correct Redis Stream, publishes the wake-up signal, and gives the client the gRPC endpoint and session token. The mobile or web client opens the stream, renders the notification, and sends a NotificationAck containing the notification ID after processing it.

Partner backend
    β”œβ”€ authenticate client β†’ Redis session key
    β”œβ”€ create notification β†’ Redis Stream
    └─ publish wake-up β†’ Redis Pub/Sub

Namma Push
    β”œβ”€ authenticate gRPC stream
    β”œβ”€ recover and read Redis Stream
    β”œβ”€ deliver notification to client
    β”œβ”€ receive NotificationAck
    └─ retry, expire, clean up, and expose metrics

Partner application
    └─ performs business action through its own backend API

The notification payload should contain a stable notification ID, category, title, body, display instructions, and an optional entity reference. The entity reference identifies the business object but does not move business authorization or transaction rules into Namma Push. A client may display a button from the notification, but the button action should call the partner backend directly.

Features partners can add around the service

Partners can build tenant-aware notification routing, per-client preference filtering, quiet hours, language selection, priority queues, notification templates, deep links, delivery analytics, unread counters, device-token management, scheduled notifications, and backend fan-out workers around this service. They can also add a separate domain or event service for order workflows, dispatch allocation, payment, fraud checks, or emergency escalation without changing the notification gateway.

Reusable speed and feature extensions

The service can be extended with small, generic infrastructure features without turning it into a business-logic service. The safest additions are features that operate on notification delivery state, routing state, or operational limits.

Extension What it does Recommended implementation
Atomic notification deduplication Prevents the same notification event from being inserted repeatedly during backend retries. Redis Lua script using SET NX or a short-lived deduplication key, with the event ID as the idempotency key.
Atomic rate limiting Limits notifications per client, tenant, category, or time window. Redis Lua token bucket or sliding-window counter with bounded TTLs.
Priority delivery Delivers safety or dispatch alerts before ordinary announcements. Separate priority Streams or priority fields with bounded reader queues.
Notification coalescing Replaces several stale updates with one current update, such as repeated location or status changes. Lua transaction that checks the latest entity key and updates the pending record atomically.
Scheduled notifications Delivers reminders or scheduled updates at a future time. Redis sorted set for due timestamps plus a bounded scheduler loop; Lua claims due entries once.
Per-client preferences Applies opt-in, quiet hours, category, and language preferences. Redis hashes for fast reads, with preference changes owned by the partner backend.
Multi-device fan-out Sends one logical notification to several active devices. Backend fan-out producer plus per-device Streams and one logical event ID.
Delivery deduplication Prevents duplicate retry work across service instances. Redis lease or claim key with a short TTL and an idempotent notification ID.
Tenant isolation Prevents one partner or application from consuming another tenant’s capacity. Tenant-prefixed keys, quotas, separate Stream groups, and per-tenant metrics.
Backpressure protection Keeps slow clients from exhausting memory or delaying healthy clients. Bounded Tokio channels, per-client send deadlines, and Redis as the durable backlog.
Presence and last-seen state Helps backends choose gRPC delivery or FCM fallback. Short-TTL Redis presence keys refreshed by the Rust service.
Delivery receipts Gives the backend a reliable delivery lifecycle signal. Append-only notification events for queued, sent, acknowledged, expired, and fallback states.

How to use Redis Lua safely

Redis Lua is appropriate when several Redis operations must behave as one short state transition. Good notification examples include deduplication, rate-limit admission, lease acquisition, scheduled-entry claiming, preference snapshot reads, and notification coalescing. A script should validate its arguments, receive every Redis key through KEYS[], use Redis server time when time comparisons matter, set bounded TTLs, and return a small deterministic result.

Backend retry
    β†’ Lua checks event_id deduplication key
    β†’ first request stores the notification and returns INSERTED
    β†’ duplicate request returns DUPLICATE
    β†’ Rust delivers only the committed notification entry

Lua scripts should not call HTTP services, databases, FCM, payment systems, or domain APIs. They should not contain ride, order, trade, pricing, fraud, or emergency business rules. Keep each script short, keep all keys for one atomic operation in the same Redis Cluster hash slot, use EVALSHA with automatic NOSCRIPT reload, and test scripts against both standalone Redis and Redis Cluster.

Staged roadmap for a partner application

A partner can adopt the platform incrementally. The first stage is reliable notification delivery with Redis Streams, Pub/Sub recovery, gRPC, ACKs, retries, FCM fallback, and basic metrics. The second stage adds notification IDs, deduplication, preferences, templates, deep links, and delivery receipts. The third stage adds priority queues, scheduling, coalescing, rate limits, tenant quotas, and multi-device fan-out. The final stage adds Redis Cluster, separate session and delivery capacity, regional deployment, load testing, and advanced Grafana alerts.

For higher scale, a partner can partition Redis Streams by client or geography, run multiple notification-service instances, use Redis Cluster with consistent key tags, separate hot delivery Redis from session Redis, add an event producer layer, and scale Prometheus/Grafana independently. These extensions should preserve the same contract: durable notification write, low-latency wake-up, gRPC delivery, client ACK, bounded retry, and idempotent processing.

What should remain outside Namma Push

Namma Push should not own pricing, authorization policy, order transactions, ride allocation, payment, inventory reservation, trade execution, fraud decisions, or emergency workflow state. Those responsibilities require domain databases, transactional boundaries, external services, and business-specific reconciliation. Keeping them outside the gateway prevents one partner’s rules from making the shared notification path slower or harder to operate.

Use Namma Push as the communication layer. Keep business meaning in the application that owns the business.

Production Docker Image and GitHub Releases

The repository includes Dockerfile.release, a multi-stage production image definition. It compiles the release binary with the locked Cargo dependency graph, copies only the binary and Dhall configuration into the runtime image, runs as a non-root user, and exposes gRPC on port 50051 and health/metrics on port 9091.

.github/workflows/release.yml is intentionally manual-only. A pushed commit or tag does not publish a release automatically. From the GitHub Actions page, choose Release notification service, select Run workflow, and enter an existing version tag such as v0.2.0-beta. A tag containing a hyphen is published as a GitHub prerelease and does not update the latest container tag. The workflow checks out that tag, builds the image for linux/amd64, publishes it to GitHub Container Registry, and creates or updates the GitHub Release.

Each release also contains the compiled Linux Rust binary and its checksum:

notification-service-linux-amd64
notification-service-linux-amd64.sha256

The checksum can be verified with:

sha256sum --check notification-service-linux-amd64.sha256

The resulting image can be pulled with:

docker pull ghcr.io/sudo-su-coffee/nammapush-rs:v0.2.0-beta
docker run --rm \
  --name nammapush \
  -p 50051:50051 \
  -p 9091:9091 \
  -e REDIS_HOST=redis \
  ghcr.io/sudo-su-coffee/nammapush-rs:v0.2.0-beta

For production, provide the partner-specific Dhall configuration through an image build or deployment-managed mounted configuration, configure Redis Cluster or Sentinel settings, and keep the image immutable. The release image is the notification transport only; partner backends remain responsible for business APIs and domain transactions.

Repository Map

The repository is organized around one notification-service binary, small client examples, and supporting operational documentation. The root contains only the primary build and configuration entry points; detailed guidance belongs under docs/.

Path Responsibility
crates/notification_service/ Rust notification gateway: gRPC streams, Redis Streams/Pub/Sub delivery, ACK handling, retries, cleanup, FCM fallback, configuration, and metrics.
crates/tests/ Workspace tests and explicitly ignored Redis/load-test experiments.
notification_service.proto Canonical notification-only protobuf shared by the Rust service and client generators.
examples/ Development integrations: Node client, browser client, and Redis mock sender. See examples/README.md.
observability/grafana/ Importable Grafana dashboard definitions.
docs/ Architecture, testing, hardening, performance, and contributor documentation.
Dockerfile.release The single canonical production image definition used by Compose and GitHub Releases.
docker-compose.yml Local Redis plus notification-service environment for development and smoke testing.
notification_service.dhall Default service configuration, with supported deployment overrides documented in README.md.

Documentation Index

The repository root intentionally keeps only the primary entry points: README.md for setup and operational orientation, and plan.md for the architecture and implementation plan. Detailed supporting documents are organized under docs/.

Document Purpose
docs/ARCHITECTURE_FLOW.md Notification, authentication, ACK, retry, expiry, FCM, and recovery flow diagrams.
docs/TESTING.md Deterministic tests, Redis-backed integration tests, and load-test guidance.
docs/SINGLE_SERVICE_HARDENING_PLAN.md Production hardening roadmap and release safeguards.
docs/main_performance_plan.md Performance optimization plan and benchmark direction.
docs/CLAUDE.md Repository-specific contributor and automation notes.

About

lightning-fast, ultra-optimized, gRPC-based push-notification service

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages