Back to articles
Technology Insight

Scaling SaaS Multi-Tenant Custom Domains: A Deep Dive into Caddy Server v2 and On-Demand TLS

June 2, 2026

Introduction: The Multi-Tenant Custom Domain Challenge

In the modern Software-as-a-Service (SaaS) landscape, offering multi-tenant custom domains has transitioned from a premium feature to a standard expectation. Whether you are building a website builder, an e-commerce platform, or a blogging network, users want to point their own domains (e.g., user-domain.com) to your infrastructure. However, managing SSL/TLS certificates for thousands or millions of external domains poses a massive engineering challenge.

Traditionally, infrastructure teams had to rely on complex cron jobs, custom Let's Encrypt scripts, or expensive enterprise reverse proxies to handle certificate provisioning. These approaches frequently suffer from rate-limiting issues, slow propagation times, and significant maintenance overhead. Enter Caddy Server v2 and its revolutionary feature: On-Demand TLS. This guide explores how to design and deploy a production-ready, highly scalable routing layer using Caddy to automate TLS for SaaS multi-tenancy.

Understanding Caddy's On-Demand TLS Architecture

Unlike traditional web servers (like Nginx or Apache) that require certificates to be pre-configured on disk before reloading the configuration, Caddy v2 can obtain certificates on-the-fly during the initial TLS handshake.

When a visitor accesses a tenant's custom domain, Caddy intercepts the TLS ClientHello. If it does not possess a valid certificate for that domain, Caddy pauses the handshake, requests a certificate from an ACME provider (such as Let's Encrypt or ZeroSSL), installs it in memory/storage, and completes the handshake—all within seconds. Subsequent requests are served instantly from Caddy's internal cache.

The Critical Security Pillar: Ask Endpoint

Allowing On-Demand TLS out of the box without restrictions introduces a severe security vulnerability. A malicious actor could point millions of wildcard DNS records to your Caddy server, forcing it to request certificates indefinitely, leading to Denial of Service (DoS) and exhausting your ACME rate limits.

To mitigate this, Caddy implements the ask directive. Before requesting a certificate, Caddy makes an internal HTTP GET request to a backend API endpoint that you control, passing the domain as a query parameter (e.g., /check-domain?domain=user-domain.com). Your backend verifies if the domain is registered to an active tenant. If the backend responds with a 200 OK, Caddy proceeds; if it returns a 400 or 404, Caddy drops the connection immediately.

Step-by-Step Implementation Guide

1. Designing the Architecture

A resilient SaaS setup typically places Caddy as an edge reverse proxy in front of your application load balancers or container clusters. Here is the operational workflow:

  • Tenant Actions: The tenant configures a CNAME record pointing their custom domain to your system domain (e.g., cname.yoursaas.com).
  • Visitor Requests: The visitor navigates to the custom domain.
  • Caddy Intervention: Caddy triggers the On-Demand TLS routine and queries your backend validation endpoint.
  • Backend Validation: Your database confirms the domain is valid and assigned to an active account.
  • Traffic Forwarding: Caddy completes the TLS handshake and reverse-proxies the traffic to your upstream web servers with proper Host headers intact.

2. Configuring the Caddyfile

Below is a production-grade Caddyfile layout optimized for On-Demand TLS multi-tenancy. It handles global configurations, rate limiting, persistence, and backend proxy routing.

{
    # Global options
    email [email protected]
    
    storage file_system {
        root /var/lib/caddy
    }

    on_demand_tls {
        ask [http://internal-api.yoursaas.internal/v1/validate-domain](http://internal-api.yoursaas.internal/v1/validate-domain)
        interval 2m
        burst 5
    }
}

# Catch-all site block for On-Demand TLS
:443 {
    tls {
        on_demand
    }

    # Proxy traffic to your main SaaS application cluster
    reverse_proxy [http://app-load-balancer.internal](http://app-load-balancer.internal) {
        header_up Host {host}
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
        header_up X-Forwarded-Proto {scheme}
    }
}

3. Developing the Validation Backend

Your backend validation service must be highly optimized and cached (using Redis or Memcached), as it will be called during the critical path of the TLS handshake for new domains or expired caches. Here is a conceptual example of how the endpoint logic behaves in a standard web service:

"When receiving a GET request on the validation route, extract the domain parameter, check it against a distributed cache, and if not found, query the primary relational database. Return status 200 strictly if the domain is mapped to a verified, un-suspended customer account."

Production Considerations and Best Practices

Deploying Caddy for multi-tenant SaaS environments requires careful planning around scaling, high availability, and storage layout.

Shared Storage for High Availability

If you run multiple instances of Caddy behind an Anycast network or a Layer 4 Cloud Load Balancer for redundancy, they must share the same storage backend. If Instance A requests a certificate, Instance B needs access to it to serve subsequent requests. Caddy supports pluggable storage modules such as caddy-dns/redis, S3, or PostgreSQL, allowing distributed instances to stay perfectly synchronized without local disk coupling.

Handling ACME Rate Limits

While Let's Encrypt provides high limits, massive concurrent onboarding spikes can hit throttling ceilings. It is highly recommended to configure Caddy to use multiple ACME issuers (e.g., configuring both Let's Encrypt and ZeroSSL as fallbacks). If one authority experiences outages or rate blocks, Caddy seamlessly falls back to the other provider without user intervention.

Pre-checking DNS Configurations

To provide a smooth User Experience (UX), your SaaS dashboard should validate the tenant's DNS settings via an asynchronous background job before suggesting they visit their live site. If your app verifies that the CNAME or A record correctly points to your proxy beforehand, you drastically minimize the number of failed TLS requests hitting your internal ask endpoint.

Conclusion

Implementing custom domain support no longer requires complex systems integration or enterprise-tier budget allocations. By leveraging Caddy v2's On-Demand TLS alongside a secure internal verification service, you can deploy an automated, secure, and infinitely scalable edge infrastructure. This architecture ensures your engineering team remains focused on building core product features rather than managing SSL certificate lifecycles.

Scaling SaaS Multi-Tenant Custom Domains: A Deep Dive into Caddy Server v2 and On-Demand TLS | DPTCloud