{"id":"69bb05e83f1c7d8bc1820635","title":"2026 03 18 Single Instance Multi Tenant Exploration","path":"how-to/technical-articles/2026-03-18-single-instance-multi-tenant-exploration","contentMarkdown":"# Single-Instance Multi-Tenant Architecture Exploration\n\n\n\nRamblers head office is in discussions about adopting NGX Ramblers as a solution to roll out to groups nationally. **The primary driver is the Brevo email integration** — Ramblers Head Office wants to offer groups a ready-made email solution (newsletters, walk notifications, booking confirmations) without each group having to set up and manage their own email infrastructure. One of their preferences is that a single NGX instance could serve multiple groups rather than the current model of one deployment per group. **Scale target: up to 500 groups.**\n\n\n## Target Architecture — outlined more detail in the following articles\n\n```mermaid\nflowchart TD\n    D1@{ icon: \"ngx:user\", label: \"group-a-ramblers.org.uk\", pos: \"b\", h: 48 }\n    D2@{ icon: \"ngx:user\", label: \"group-b-ramblers.org.uk\", pos: \"b\", h: 48 }\n    DN@{ icon: \"ngx:user\", label: \"...up to 500 domains\", pos: \"b\", h: 48 }\n\n    D1 --> CF\n    D2 --> CF\n    DN --> CF\n\n    CF@{ icon: \"ngx:cloudflare\", label: \"Cloudflare DNS\", pos: \"b\", h: 48 }\n    CF --> FLY\n\n    subgraph FLY[\"Fly.io Application - 2 to 4 instances\"]\n        TM[\"Tenant Resolution Middleware<br/>Host header to groupCode\"]\n        CACHE[\"Domain-to-group cache<br/>refreshed periodically\"]\n        DBR[\"Database Router<br/>groupCode to mongoose.useDb\"]\n        TM --> CACHE\n        TM --> DBR\n    end\n\n    DBR --> MDB1@{ icon: \"ngx:mongodb\", label: \"Group A DB\", pos: \"b\", h: 48 }\n    DBR --> MDB2@{ icon: \"ngx:mongodb\", label: \"Group B DB\", pos: \"b\", h: 48 }\n    DBR --> MDBN@{ icon: \"ngx:mongodb\", label: \"Group N DB\", pos: \"b\", h: 48 }\n\n    MDB1 --> S3\n    MDB2 --> S3\n    MDBN --> S3\n\n    S3@{ icon: \"ngx:aws\", label: \"Single S3 Bucket<br/>/{groupCode}/images/\", pos: \"b\", h: 48 }\n\n    style FLY fill:#E8F5EE,stroke:#9BC8AB,stroke-width:2px,rx:12,ry:12,color:#404143\n```\n\n\n_____\n\nThis series of articles explores what would be required to re-architect NGX Ramblers so that any number of groups run off a single application instance, while maintaining the same segregated user experience — where navigating to a group's domain shows only that group's branding, members, walks, and content.\n\n\n## Platform Overview\n\nWhat NGX Ramblers provides beyond email — walks, bookings, galleries, CMS, and more\n\n![](https://ngx-ramblers.org.uk/api/aws/s3/site-content/fb7500d8-1a94-4527-a62f-969e5843f960.jpg)\n\n## Current Architecture\n\nHow the per-group deployment model works today — one Docker image, 13 independent apps\n\n![](https://ngx-ramblers.org.uk/api/aws/s3/site-content/fb7500d8-1a94-4527-a62f-969e5843f960.jpg)\n\n## Proposed Architecture\n\nSingle-instance multi-tenant design — tenant resolution, database switching, request lifecycle\n\n![](https://ngx-ramblers.org.uk/api/aws/s3/site-content/fb7500d8-1a94-4527-a62f-969e5843f960.jpg)\n\n## Brevo Email at Scale\n\nThe primary rollout driver — outbound email, deliverability, and multi-tenant email isolation\n\n![](https://ngx-ramblers.org.uk/api/aws/s3/site-content/fb7500d8-1a94-4527-a62f-969e5843f960.jpg)\n\n## Billing and Costs\n\nFly.io free-tier analysis, cost comparison at 500 groups, and billing risk assessment\n\n![](https://ngx-ramblers.org.uk/api/aws/s3/site-content/fb7500d8-1a94-4527-a62f-969e5843f960.jpg)\n\n## Assessment and Recommendation\n\nHonest pros and cons, effort estimates (AI-assisted vs manual), and recommended approach\n\n![](https://ngx-ramblers.org.uk/api/aws/s3/site-content/fb7500d8-1a94-4527-a62f-969e5843f960.jpg)","contentHtml":"<h1>Single-Instance Multi-Tenant Architecture Exploration</h1>\n<p>Ramblers head office is in discussions about adopting NGX Ramblers as a solution to roll out to groups nationally. <strong>The primary driver is the Brevo email integration</strong> — Ramblers Head Office wants to offer groups a ready-made email solution (newsletters, walk notifications, booking confirmations) without each group having to set up and manage their own email infrastructure. One of their preferences is that a single NGX instance could serve multiple groups rather than the current model of one deployment per group. <strong>Scale target: up to 500 groups.</strong></p>\n<h2>Target Architecture — outlined more detail in the following articles</h2>\n<pre><code class=\"language-mermaid\">flowchart TD\n    D1@{ icon: &quot;ngx:user&quot;, label: &quot;group-a-ramblers.org.uk&quot;, pos: &quot;b&quot;, h: 48 }\n    D2@{ icon: &quot;ngx:user&quot;, label: &quot;group-b-ramblers.org.uk&quot;, pos: &quot;b&quot;, h: 48 }\n    DN@{ icon: &quot;ngx:user&quot;, label: &quot;...up to 500 domains&quot;, pos: &quot;b&quot;, h: 48 }\n\n    D1 --&gt; CF\n    D2 --&gt; CF\n    DN --&gt; CF\n\n    CF@{ icon: &quot;ngx:cloudflare&quot;, label: &quot;Cloudflare DNS&quot;, pos: &quot;b&quot;, h: 48 }\n    CF --&gt; FLY\n\n    subgraph FLY[&quot;Fly.io Application - 2 to 4 instances&quot;]\n        TM[&quot;Tenant Resolution Middleware&lt;br/&gt;Host header to groupCode&quot;]\n        CACHE[&quot;Domain-to-group cache&lt;br/&gt;refreshed periodically&quot;]\n        DBR[&quot;Database Router&lt;br/&gt;groupCode to mongoose.useDb&quot;]\n        TM --&gt; CACHE\n        TM --&gt; DBR\n    end\n\n    DBR --&gt; MDB1@{ icon: &quot;ngx:mongodb&quot;, label: &quot;Group A DB&quot;, pos: &quot;b&quot;, h: 48 }\n    DBR --&gt; MDB2@{ icon: &quot;ngx:mongodb&quot;, label: &quot;Group B DB&quot;, pos: &quot;b&quot;, h: 48 }\n    DBR --&gt; MDBN@{ icon: &quot;ngx:mongodb&quot;, label: &quot;Group N DB&quot;, pos: &quot;b&quot;, h: 48 }\n\n    MDB1 --&gt; S3\n    MDB2 --&gt; S3\n    MDBN --&gt; S3\n\n    S3@{ icon: &quot;ngx:aws&quot;, label: &quot;Single S3 Bucket&lt;br/&gt;/{groupCode}/images/&quot;, pos: &quot;b&quot;, h: 48 }\n\n    style FLY fill:#E8F5EE,stroke:#9BC8AB,stroke-width:2px,rx:12,ry:12,color:#404143\n</code></pre>\n<hr>\n<p>This series of articles explores what would be required to re-architect NGX Ramblers so that any number of groups run off a single application instance, while maintaining the same segregated user experience — where navigating to a group&#39;s domain shows only that group&#39;s branding, members, walks, and content.</p>\n<h2>Platform Overview</h2>\n<p>What NGX Ramblers provides beyond email — walks, bookings, galleries, CMS, and more</p>\n<p><img src=\"https://ngx-ramblers.org.uk/api/aws/s3/site-content/fb7500d8-1a94-4527-a62f-969e5843f960.jpg\" alt=\"\"></p>\n<h2>Current Architecture</h2>\n<p>How the per-group deployment model works today — one Docker image, 13 independent apps</p>\n<p><img src=\"https://ngx-ramblers.org.uk/api/aws/s3/site-content/fb7500d8-1a94-4527-a62f-969e5843f960.jpg\" alt=\"\"></p>\n<h2>Proposed Architecture</h2>\n<p>Single-instance multi-tenant design — tenant resolution, database switching, request lifecycle</p>\n<p><img src=\"https://ngx-ramblers.org.uk/api/aws/s3/site-content/fb7500d8-1a94-4527-a62f-969e5843f960.jpg\" alt=\"\"></p>\n<h2>Brevo Email at Scale</h2>\n<p>The primary rollout driver — outbound email, deliverability, and multi-tenant email isolation</p>\n<p><img src=\"https://ngx-ramblers.org.uk/api/aws/s3/site-content/fb7500d8-1a94-4527-a62f-969e5843f960.jpg\" alt=\"\"></p>\n<h2>Billing and Costs</h2>\n<p>Fly.io free-tier analysis, cost comparison at 500 groups, and billing risk assessment</p>\n<p><img src=\"https://ngx-ramblers.org.uk/api/aws/s3/site-content/fb7500d8-1a94-4527-a62f-969e5843f960.jpg\" alt=\"\"></p>\n<h2>Assessment and Recommendation</h2>\n<p>Honest pros and cons, effort estimates (AI-assisted vs manual), and recommended approach</p>\n<p><img src=\"https://ngx-ramblers.org.uk/api/aws/s3/site-content/fb7500d8-1a94-4527-a62f-969e5843f960.jpg\" alt=\"\"></p>\n"}