1/10/2026BharatOPD

High-Availability Redirection Architecture: How BharatOPD Scales Dynamic Portfolio Links & Patient Router URLs

A deep dive into edge routing and Redis clusters behind bharatopd.com/<website> and short routing tokens at bharatopd.com/r/<website>.

High-Availability Redirection Architecture: How BharatOPD Scales Dynamic Portfolio Links & Patient Router URLs

High-Availability Redirection Architecture: How BharatOPD Scales Dynamic Portfolio Links & Patient Router URLs

In modern healthcare SaaS platforms, high-speed, dynamic routing is a mission-critical subsystem. In building BharatOPD, we were tasked with engineering a lightning-fast custom domain and link shortening system capable of serving millions of patients and doctors across India.

Doctors need beautiful, memorable landing pages directly hosted at custom URL schemas: bharatopd.com/<clinic-or-doctor-handle>.

Simultaneously, transactional SMS and WhatsApp notifications must include ultra-short redirection URLs carrying cryptographic tokens: bharatopd.com/r/<redirection-token> to route patients to their digital prescriptions, billing pages, or booking workflows.

Here is how we designed and scaled this Edge redirection architecture to achieve a sub-50ms latency response profile.


1. The Redirection Pipeline Architecture

Querying relational database clusters (like PostgreSQL) on every single link redirect introduces major database CPU overhead and latency drift.

To solve this, we decoupled the resolution layer from the primary database cluster, implementing Next.js Edge Middleware backed by a globally replicated Redis cluster (ElastiCache).

[ Patient Device / Browser Request ]
                 │
                 ▼
     [ Next.js Edge Middleware ] ──► (Cache Lookup)
                 │                         │
                 │                         ├──► [ Redis Global Cache ] (Hit: Sub-15ms Redirection)
                 │                         │
                 ▼ (Cache Miss)            ▼
[ Node.js Microservice Node ] ──► [ PostgreSQL Replica Pool ]
                 │
                 ▼ (Write & Populate Cache)
     [ Redis Cluster Node ]

The Optimization Stages:

  1. Edge Interception: Incoming requests to /r/[token] or dynamic user handles are intercepted by middleware before reaching the server routing bundle.
  2. High-Speed Redis Check: The middleware queries a highly available Redis cache layer. The key structure for a dynamic handle is mapped as handle:<website> and for a redirect token as redirect:<token>.
  3. PostgreSQL Fallback: On cache misses, the query hits an active-read PostgreSQL replica database, populates the Redis cache with a 24-hour expiration token (TTL), and executes a standard HTTP 302 Found redirection header.

2. Technical Blueprint: Edge Redirection Middleware (Node.js & Redis)

Here is the production-ready middleware controller designed to handle dynamic handle parsing and shortened redirects efficiently:

const Redis = require('ioredis');
const db = require('../lib/db');

// Instantiating secure Redis connection
const redis = new Redis(process.env.REDIS_URL || 'redis://127.0.0.1:6379');

async function handleRedirection(req, res) {
  const { path } = req;
  const parts = path.split('/').filter(Boolean);

  if (parts.length === 0) return res.redirect('/');

  try {
    // Case A: Short Redirect URLs -> bharatopd.com/r/<website>
    if (parts[0] === 'r' && parts[1]) {
      const shortToken = parts[1];
      const cacheKey = `redirect:${shortToken}`;
      
      // 1. Inspect Redis memory store first
      let destinationUrl = await redis.get(cacheKey);
      
      if (destinationUrl) {
        return res.status(301).redirect(destinationUrl);
      }
      
      // 2. Query Postgres db on cache miss
      const record = await db('short_links')
        .where('token', shortToken)
        .first();
        
      if (record) {
        destinationUrl = record.destination_url;
        // Write back to Redis cache with 1 day TTL
        await redis.setex(cacheKey, 86400, destinationUrl);
        return res.status(301).redirect(destinationUrl);
      }
      
      return res.status(404).render('not-found');
    }

    // Case B: Dynamic Doctor Portfolio handles -> bharatopd.com/<website>
    const handle = parts[0];
    const portfolioCacheKey = `handle:${handle}`;
    
    let portfolioData = await redis.get(portfolioCacheKey);
    
    if (portfolioData) {
      const parsed = JSON.parse(portfolioData);
      return res.render('doctor-portfolio', { doctor: parsed });
    }
    
    // Query database on cache miss
    const doctor = await db('doctors')
      .where('username_handle', handle)
      .first();
      
    if (doctor) {
      // Cache portfolio details with 1 hour TTL
      await redis.setex(portfolioCacheKey, 3600, JSON.stringify(doctor));
      return res.render('doctor-portfolio', { doctor });
    }
    
    // Fallback to normal routing if no matching handle is found
    return res.status(404).render('not-found');
  } catch (error) {
    console.error('Routing redirection failure:', error);
    return res.status(500).render('server-error');
  }
}

module.exports = { handleRedirection };

3. SEO Compliance and Link Integrity

When routing dynamic paths, keeping SEO rankings high for doctor index pages is essential.

  • Permanent Redirects (301): We employ strict HTTP 301 Moved Permanently headers for short links (/r/...) targeting patient portals. This signals to search crawler bots that link equity must flow directly to the primary target landing page.
  • Dynamic Canonical Tags: Dynamic doctor profile pages automatically generate a canonical URL tag matching <link rel="canonical" href="https://bharatopd.com/dr-name" /> to avoid duplicate content flags by Google's indexing algorithms.

4. The Engineering Takeaway

Our success engineering the redirection and routing infrastructure for BharatOPD demonstrates AppRinger's capability to build lightning-fast systems. From dynamic path resolution to edge caching and secure domain masking, we compile robust frameworks that scale cleanly to meet high-volume user demands.

Chat with us