Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

High Availability Architecture Patterns

By Kokil Thapa | Last reviewed: September 2026

High Availability Architecture Patterns exist because downtime costs money, trust, and sleep. A booking form that dies during peak season, or a legal portal that drops mid-upload, is not a minor bug—it is a business outage. On production enterprise Laravel and PHP systems I maintain, availability is rarely about exotic cloud magic. It is about redundant components, fast failover, health checks, and honest trade-offs your team can operate at 2 a.m.

What Are High Availability Architecture Patterns?

High availability (HA) means your system keeps serving correct requests when individual parts fail. You do not eliminate failure—you design around it. The goal is measurable: uptime (often 99.9% or 99.99%) and recovery time objective (RTO), how fast service returns after an incident.

Most web HA stacks share the same building blocks:

  • Redundancy — at least two of everything critical: app servers, load balancers, database replicas.
  • Health checks — automated probes that remove bad nodes from traffic.
  • Failover — promotion of a standby or rerouting to a healthy peer.
  • State externalisation — sessions and cache off the app box, usually in Redis.
  • Observability — logs, metrics, and alerts that tell you something broke before users do.
HA Stack OverviewUsers / CDNLoad BalancerHealth ChecksApp Server APHP-FPM / LaravelApp Server BPHP-FPM / LaravelRedis CacheSessions + QueueMySQL ClusterPrimary + ReplicaShared State
High Availability Architecture Patterns stack: redundant app tier, externalised state, and replicated database.

On a legal-tech portal or eCommerce site, HA is not vanity metrics. Payment callbacks, document uploads, and booking holds depend on consistent uptime. I treat HA as part of initial architecture—not a post-launch patch after the first outage.

How Do Active-Passive and Active-Active HA Patterns Compare?

The first architectural fork is how you run redundant application nodes. Active-passive keeps one node serving traffic while a standby waits. Active-active sends traffic to all healthy nodes at once. Both are valid High Availability Architecture Patterns; the wrong choice is picking one your team cannot operate.

PatternHow it worksBest forTrade-offs
Active-passivePrimary serves; standby promoted on failureSmall teams, single-region Laravel apps, budget-sensitive Nepal SMB sitesLower cost; standby hardware idle; failover must be tested
Active-activeAll nodes serve traffic behind a load balancerHigh-traffic eCommerce, API platforms, multi-region servicesHigher cost; needs shared session/cache; harder debugging
Multi-AZ / multi-regionReplicas in separate failure domainsCritical booking and payment systemsLatency, data sync complexity, higher spend
Blue-green deployTwo full environments; switch traffic atomicallyZero-downtime releases on monolithsDouble infra during cutover; schema migration care

For many Laravel 12 or Laravel 13 apps on PHP 8.3+, active-active behind Nginx or HAProxy is the sweet spot. Two Ubuntu app servers, one load balancer, Redis for sessions, and MySQL primary-replica replication cover most real client workloads without Kubernetes overhead.

When active-passive is the right call

If you run a brochure site plus a small admin panel, active-passive on a single VPS pair may be enough. Keepalived can float a virtual IP between two nodes. When the primary dies, the VIP moves to the standby. This pattern is simple and cheap—often Rs 8,000–15,000/month (~USD 60–110) for two modest VPS instances in Nepal or abroad.

When active-active earns its cost

Seasonal traffic spikes—flower delivery during festivals, trek bookings in autumn—need horizontal scale. Active-active lets you add app nodes without rewriting the app. The catch: every node must be stateless. Push sessions to Redis 8.10, files to S3-compatible storage, and queues to Redis or a dedicated worker.

Active-Passive vs Active-ActiveActive-PassiveActive-ActivePrimary Node (Live)Standby Node (Idle)Failover on deathApp Node 1 (Live)App Node 2 (Live)Shared Redis + MySQL ReplicaBoth patterns need externalised state for true HAActive-active adds concurrent capacity + faster recovery
Comparing two core High Availability Architecture Patterns: standby promotion versus parallel serving.

How Do You Configure Load Balancers for High Availability?

Load balancers are the traffic cops of HA. They distribute requests, terminate TLS, and—critically—run health checks that pull failed backends out of rotation. Without health checks, users hit dead servers until someone notices.

A typical Nginx upstream block for two Laravel app servers looks like this:

upstream laravel_app {
    least_conn;
    server 10.0.1.11:8080 max_fails=3 fail_timeout=30s;
    server 10.0.1.12:8080 max_fails=3 fail_timeout=30s;
    keepalive 32;
}

server {
    listen 443 ssl http2;
    server_name app.example.com;

    location / {
        proxy_pass http://laravel_app;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }

    location /health {
        access_log off;
        return 200 "ok";
    }
}

Each app server should expose a dedicated health endpoint—not just the homepage. A homepage can return 200 while the database connection is broken. I prefer a lightweight /health route that checks DB and Redis:

Route::get('/health', function () {
    DB::connection()->getPdo();
    Redis::connection()->ping();

    return response('ok', 200);
});

Load balancer HA itself

Your load balancer must not be a single point of failure. Options include:

  1. Managed load balancer — AWS ALB, DigitalOcean LB, Cloudflare Load Balancing. Vendor handles redundancy.
  2. Dual Nginx + Keepalived — two LB nodes share a floating VIP. Common on self-managed Ubuntu servers.
  3. DNS failover — last-resort pattern; TTL delays hurt RTO. Use with active health monitoring.

On sister sites I deploy with Deployer 7 and GitLab CI, the load balancer health check path must match the post-deploy symlink. A stale cron or wrong PHP binary can pass HTTP checks but fail queue workers—a reason I monitor workers separately.

What Database Patterns Support High Availability?

The database is usually the hardest HA layer. Application servers are cheap to duplicate. MySQL 9.7 or PostgreSQL 18 data must stay consistent across replicas and survive primary failure without corruption.

Common patterns:

  • Primary-replica (async replication) — reads scale to replicas; writes go to primary. Failover promotes a replica. Small replication lag window.
  • Semi-sync replication — primary waits for at least one replica ack before commit. Tighter consistency, slightly higher write latency.
  • Managed HA — RDS Multi-AZ, Cloud SQL HA, or DigitalOcean managed databases handle failover automatically.
  • Galera / Group Replication — multi-primary or single-primary clusters. Stronger consistency; more operational complexity.

For Laravel apps, read/write splitting needs explicit configuration. Eloquent does not magically route reads to replicas—you configure a read connection in config/database.php and use it for reporting queries. Write operations always hit the primary.

'mysql' => [
    'driver' => 'mysql',
    'read' => [
        'host' => ['10.0.2.21', '10.0.2.22'],
    ],
    'write' => [
        'host' => ['10.0.2.20'],
    ],
    'sticky' => true,
    /* ... */
],

After failover, update DNS or proxy config so the new primary receives writes. Tools like Orchestrator or Patroni automate MySQL and PostgreSQL promotion. Manual promotion works for small teams—if you rehearse it quarterly. A failover you have never tested is not HA; it is hope.

See also: PostgreSQL replication and high availability and MySQL query optimisation for high-traffic apps—slow queries become outages under failover load.

Database Failover Sequence1. PrimaryFails2. DetectHealth Probe3. PromoteReplica4. RouteWritesApp servers retry writes via new primaryConnection pools flush stale handlesOld PrimaryRebuild as replicaNew PrimaryServes all writesTarget RTO under 60 seconds for payment-critical apps
Database failover flow within High Availability Architecture Patterns: detect, promote, reroute, rebuild.

How Do Caching and Queues Fit Into HA Design?

Redis is the glue in most PHP HA stacks. It holds sessions, cache, rate-limit counters, and Laravel queue backends. A single Redis instance is a single point of failure—so run Redis with replication or use a managed Redis service.

For Laravel 12/13 on PHP 8.3+, configure sessions and cache to Redis from day one:

SESSION_DRIVER=redis
CACHE_STORE=redis
QUEUE_CONNECTION=redis

REDIS_HOST=10.0.3.10
REDIS_PASSWORD=null
REDIS_PORT=6379

Redis Sentinel or Redis Cluster provides automatic failover when the master dies. Laravel supports Sentinel via the redis config options array. At minimum, run a primary-replica pair and monitor replication lag.

Queue workers deserve the same HA thinking as web workers. If all queue workers run on one box and it dies, emails, webhooks, and PDF generation stall. Run workers on both app nodes under Supervisor, or dedicate a worker node with the same deploy pipeline. I have seen payment webhooks pile up during a worker outage—then flood the gateway when service returns. Use circuit breakers and backoff on outbound integrations.

Application-level caching reduces database load during partial failures. When a replica is slow, a warm Redis cache keeps product pages alive. Patterns like cache-aside and stale-while-revalidate are covered in Redis caching patterns for web apps and caching strategies for high-traffic sites.

What Resilience Patterns Complement High Availability?

HA keeps nodes alive. Resilience keeps the application graceful when dependencies degrade. The two layers work together.

Circuit breakers

When a third-party SMS or payment API times out, retry storms can take down your app. Circuit breakers stop calling a failing service after a threshold, fail fast, and retry after a cooldown. Laravel packages like laravel-circuit-breaker or custom middleware can wrap HTTP clients.

Graceful degradation

Not every feature needs 99.99%. A lawyer directory can serve cached listings if search is down. An eCommerce checkout cannot. Map features to tiers: critical path (auth, cart, payment) versus nice-to-have (recommendations, live chat).

Idempotent webhooks and jobs

HA failover causes duplicate deliveries. Payment gateways retry callbacks; queue workers re-process jobs. Design handlers to be idempotent—use unique constraint keys on gateway transaction IDs. See webhook design patterns for reliability.

API gateway and rate limiting

An API gateway centralises auth, throttling, and routing. During traffic spikes it protects backend pools. Useful for multi-service setups; optional for monoliths behind Nginx rate limits. Compare approaches in API gateway patterns explained.

HA + Resilience LayersLayer 1: Load Balancer + Multi-Node AppsLayer 2: Redis Cache + DB ReplicationLayer 3: Circuit Breakers + Retry BackoffLayer 4: Monitoring + Runbooks + Failover DrillsEach layer absorbs a class of failureSkip any layer and outages become user-facing fastTest failover quarterly at minimum
High Availability Architecture Patterns work best stacked with resilience and operational layers.

How Do You Implement HA on a Real Laravel Production Stack?

Theory is cheap. Here is a reference stack I have used on booking and eCommerce Laravel apps—adaptable for Nepal hosting budgets and global clients alike.

Reference topology

  1. Two app servers — Ubuntu 24, PHP 8.3/8.4 FPM, identical code via Deployer symlink releases.
  2. One managed or dual load balancer — TLS termination, health checks on /health.
  3. Redis Sentinel trio — or managed Redis for sessions, cache, queues.
  4. MySQL primary + two replicas — async replication; Orchestrator for failover.
  5. Separate worker supervisionsupervisor on both app nodes running php artisan queue:work.
  6. Object storage — S3 or compatible for uploads; never local disk on app nodes.
  7. Monitoring — Uptime probes, slow query log, queue depth alerts, disk space.

PHP-FPM pool sizing matters under HA. Too few workers and failover traffic saturates pools. Too many and memory exhausts the box. Tune per server RAM—guidance in PHP-FPM tuning for high-traffic websites and PHP-FPM pool tuning.

For a trek booking platform like Adventure Third Pole Trek, peak-season traffic justifies active-active. For a law-firm portal like Mijar Law Associates, active-passive with solid backups may be enough—document uploads and client auth still need tested recovery.

Deployment without downtime

Zero-downtime deploy on multiple nodes:

  1. Deploy to node B; wait for health check pass.
  2. Drain node A from load balancer; finish in-flight requests.
  3. Deploy node A; re-add to pool.
  4. Repeat for node B. Run migrations before traffic switch if schema is backward-compatible.

Run php artisan config:cache and reload PHP-FPM after each deploy. Opcache must see new code—another production gotcha I hit on shared EC2 pipelines.

Cost reality for Nepal teams

Full HA is not free. A modest dual-server setup with managed DB and Redis might run Rs 25,000–40,000/month (~USD 185–295). Enterprise multi-AZ higher. Match spend to revenue at risk—a Rs 500/month brochure site does not need Galera. A payment-processing store does.

Hosting choices affect HA options. Domain and hosting decisions and Linux system administration determine whether you get floating IPs, managed failover, or single-box limits. Use the JSON formatter when debugging API health payloads during load balancer setup.

Key Takeaways

  • High Availability Architecture Patterns combine redundant app nodes, load-balanced traffic, replicated databases, and externalised Redis state.
  • Active-active suits traffic spikes; active-passive suits smaller budgets—both require tested failover, not just spare hardware.
  • Health checks must validate DB and Redis connections, not just HTTP 200 on the homepage.
  • Database failover is the hardest layer—automate promotion and rehearse it before production incidents.
  • Stack resilience patterns (circuit breakers, idempotent jobs, queue redundancy) prevent HA from becoming a retry storm.
  • Match HA spend to business impact: payment and booking paths deserve more redundancy than brochure content.

People Also Ask

What uptime should a web application target?

99.9% ("three nines") allows about 8.7 hours downtime per year—reasonable for many SMB sites. Payment, booking, and SaaS platforms often aim for 99.95% or 99.99%. Define uptime per critical endpoint, not just the marketing homepage.

Is Kubernetes required for high availability?

No. Two app servers, Nginx, Redis, and MySQL replication deliver solid HA for most Laravel monoliths. Kubernetes helps at scale and for microservices, but it adds operational overhead small teams may not need. See Kubernetes architecture explained for when it makes sense.

How do you test high availability without breaking production?

Run quarterly game days: kill one app node, block database primary traffic, verify promotion and alerts. Use staging mirrors of production topology. Chaos tools like toxiproxy simulate latency. Document results in a runbook your on-call can follow.

What is the difference between HA and disaster recovery?

HA handles component failure within the same region—server death, disk crash, process hang. Disaster recovery (DR) handles region-wide loss—datacentre fire, ISP outage. HA targets minutes of RTO; DR may accept hours if backups restore to another region. You need both for critical systems.

Build HA That Survives Real Outages

High Availability Architecture Patterns are not a checklist you finish once. They are operational habits: redundant nodes, honest health checks, rehearsed failover, and resilience around third-party dependencies. Start with stateless app servers and Redis sessions, add database replication, then layer circuit breakers and monitoring. The stack on a production eCommerce deployment or legal portal does not need to look like Netflix—but it must survive the failure you know is coming.

If you want help designing or hardening HA for a Laravel, WordPress, or custom PHP platform, review our support and maintenance services or testing and optimisation work. For architecture from scratch, see modern Laravel architecture best practices and hosting a high-traffic Nepali eCommerce site. External references worth bookmarking: the AWS Well-Architected Reliability pillar and Nginx load balancing documentation.

Contact us to review your current stack, define RTO targets, and implement High Availability Architecture Patterns your team can actually run.

Frequently Asked Questions

High availability architecture patterns combine redundant app servers, load-balanced traffic, database replication with automatic failover, and cached reads so one failed node does not take the whole system offline. The goal is measurable uptime—often 99.9% or better—and a defined recovery time objective after incidents.

99.9% ("three nines") allows about 8.7 hours downtime per year—reasonable for many SMB sites. Payment, booking, and SaaS platforms often aim for 99.95% or 99.99%. Define uptime per critical endpoint, not just the marketing homepage.

No. Two app servers, Nginx, Redis, and MySQL replication deliver solid HA for most Laravel monoliths. Kubernetes helps at scale and for microservices, but it is not a prerequisite for redundant PHP web stacks.

Active-passive keeps one node serving while a standby waits for promotion on failure—lower cost, simpler for small teams, but idle standby hardware. Active-active sends traffic to all healthy nodes behind a load balancer—better for traffic spikes and eCommerce, but every node must be stateless with sessions in Redis and files on object storage. Both are valid; the wrong choice is picking one your team cannot operate and test at 2 a.m.

Active-passive suits brochure sites with small admin panels, budget-sensitive Nepal SMB sites, and single-region Laravel apps where a Keepalived floating VIP between two VPS nodes is enough. Active-active earns its cost when seasonal traffic spikes—festival flower delivery, autumn trek bookings—need horizontal scale without rewriting the application. Match the pattern to team size, traffic shape, and whether you can externalise state to Redis and S3-compatible storage from day one.

Load balancers distribute requests, terminate TLS, and run health checks that remove failed backends from rotation. A typical Nginx upstream uses least_conn with max_fails and fail_timeout per app server. Each Laravel node should expose a dedicated /health route that verifies database and Redis connections—not just HTTP 200 on the homepage, which can pass while dependencies are broken. Proxy headers for Host, X-Real-IP, X-Forwarded-For, and X-Forwarded-Proto keep Laravel routing correct behind the balancer.

Options include managed load balancers where the vendor handles redundancy—AWS ALB, DigitalOcean LB, or Cloudflare Load Balancing—or dual Nginx nodes with Keepalived sharing a floating VIP on self-managed Ubuntu servers. DNS failover is a last-resort pattern because TTL delays hurt recovery time; pair it with active health monitoring. On Deployer 7 and GitLab CI pipelines, ensure the health check path matches the post-deploy symlink so stale cron paths or wrong PHP binaries do not slip through HTTP checks alone.

Primary-replica async replication scales reads and promotes a replica on primary failure, with a small lag window. Semi-sync replication waits for at least one replica ack before commit—tighter consistency, slightly higher write latency. Managed HA through RDS Multi-AZ, Cloud SQL, or DigitalOcean managed databases automates failover. Galera or Group Replication offers stronger consistency but more operational complexity. For Laravel, configure explicit read/write splitting in config/database.php with sticky sessions—Eloquent does not automatically route reads to replicas.

Application servers are cheap to duplicate; MySQL 9.7 or PostgreSQL 18 data must stay consistent across replicas and survive primary failure without corruption. After promotion, update DNS or proxy config so the new primary receives writes. Tools like Orchestrator or Patroni automate MySQL and PostgreSQL promotion; manual promotion works for small teams only if rehearsed quarterly. A failover you have never tested is not HA—it is hope. Slow queries become outages under failover load, so query optimisation matters alongside replication.

Redis 8.10 holds sessions, cache, rate-limit counters, and Laravel queue backends. A single Redis instance is a single point of failure—run replication, Sentinel, or Cluster for automatic master failover. Configure SESSION_DRIVER=redis, CACHE_STORE=redis, and QUEUE_CONNECTION=redis from day one on Laravel 12 or 13. Run queue workers on both app nodes under Supervisor; if all workers sit on one box, emails, webhooks, and PDF generation stall during that node's outage. Warm Redis cache keeps product pages alive when a database replica is slow.

HA keeps nodes alive; resilience keeps the application graceful when dependencies degrade. Circuit breakers stop retry storms against failing payment or SMS APIs. Graceful degradation maps features to tiers—checkout is critical, live chat is not. Idempotent webhook and job handlers prevent duplicate charges when failover causes redelivery. An API gateway centralises auth and throttling for multi-service setups; monoliths can use Nginx rate limits instead. Stack these layers together rather than treating spare hardware alone as sufficient protection.

A reference topology uses two Ubuntu 24 app servers with PHP 8.3 or 8.4 FPM and identical Deployer symlink releases, one managed or dual load balancer with TLS and /health checks, Redis Sentinel or managed Redis, MySQL primary plus two async replicas with Orchestrator for failover, Supervisor queue workers on both nodes, and S3-compatible object storage instead of local disk for uploads. Tune PHP-FPM pool sizing per server RAM—too few workers saturate under failover traffic; too many exhaust memory. Add uptime probes, slow query alerts, queue depth monitoring, and disk space checks.

Deploy to node B and wait for the health check to pass. Drain node A from the load balancer and finish in-flight requests. Deploy node A and re-add it to the pool. Repeat for node B. Run migrations before the traffic switch if schema changes are backward-compatible. Run php artisan config:cache and reload PHP-FPM after each deploy so opcache sees new code—a common production gotcha on shared EC2 pipelines. Blue-green deploy with two full environments offers atomic traffic switching but doubles infrastructure during cutover and needs careful schema migration planning.

A modest active-passive pair on two VPS instances often runs Rs 8,000–15,000 per month (~USD 60–110). Full HA with dual app servers, managed database, and managed Redis typically lands at Rs 25,000–40,000 per month (~USD 185–295); enterprise multi-AZ setups cost more. Match spend to revenue at risk—a Rs 500 per month brochure site does not need Galera clustering. A payment-processing store or booking platform during peak season does. Hosting choices determine whether you get floating IPs, managed failover, or single-box limits.

Homepage checks return 200 while the database connection is broken, so each app server needs a lightweight /health route that calls DB::connection()->getPdo() and Redis::connection()->ping() before returning ok. Load balancer probes should target that endpoint with max_fails and fail_timeout configured per upstream server. Monitor queue workers separately—HTTP checks can pass while workers are dead, causing payment webhooks and emails to pile up until the gateway floods on recovery. Observability through logs, metrics, and alerts should tell you something broke before users report it.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: