Azure Database for PostgreSQL — Budget Proposal
Date: 2026-02-17 Project: Dust Ranger Data Management System Purpose: Cost estimation for migrating from self-hosted Supabase (Oracle Cloud VM) to Azure Database for PostgreSQL Flexible Server with a self-built C# ASP.NET Core backend.
1. Architecture Overview
React Frontend → C# ASP.NET Core Backend (Oracle Cloud VM, Docker) → Azure PostgreSQL (Flexible Server)- Frontend: React (unchanged)
- Backend: C# ASP.NET Core, containerized on existing Oracle Cloud VM (no additional compute cost)
- Database: Azure Database for PostgreSQL Flexible Server
- Edge Functions: Consolidated into C# backend (12 Supabase Edge Functions replaced)
- File Storage: Remains on existing infrastructure
2. Current Database Profile
| Metric | Value |
|---|---|
| Total database size | 7.2 GB (7.5 months of data) |
| Projected size at 1 year | ~20 GB |
| Largest table | data_dust_ranger — 7.5M rows, 4,040 MB |
| Second largest | data_heatmap — 6.7M rows, 3,297 MB |
| All other tables combined | ~28 MB |
| Total tables | 52 |
| Database functions/triggers | 96 |
| RLS policies | 282 |
| Indexes | 69 |
| Active devices | 17 |
Weekly Data Ingestion
| Metric | Value |
|---|---|
| Raw JSONL files | ~660 MB/week |
| Database with indexes | ~355 MB/week |
| Pure data | ~220 MB/week |
| Row count | ~910,000 rows/week |
Annual Growth
| Metric | Value |
|---|---|
| Raw files | ~34 GB/year |
| Database with indexes | ~18 GB/year |
| Pure data | ~11 GB/year |
3. Recommended Configuration
| Parameter | Value |
|---|---|
| Service | Azure Database for PostgreSQL Flexible Server |
| Region | Australia East (Sydney) |
| Compute Series | General Purpose Dsv3 (D2s v3) |
| Specification | 2 vCores, 8 GB RAM |
| Storage | 30 GiB Premium SSD (initial) |
| Backup | LRS, 7-day retention (within free allowance) |
| PostgreSQL Version | 16 |
| Connection Pooling | PgBouncer enabled, transaction mode |
| High Availability | Disabled |
| Network | Public access with firewall (Oracle VM IP only) + SSL enforced |
4. Pricing Plans Comparison
All prices in USD.
Plan A: Burstable B2ms — Pay-as-you-go (No Reserved option)
| Item | Monthly |
|---|---|
| Compute (B2ms, 2 vCores, 8 GB) | $151.84 |
| Storage 30 GiB | $5.01 |
| Backup (LRS) | $0.00 |
| Total | $156.85 |
| Annual | $1,882 |
Plan B: General Purpose Dsv3 — 1-Year Reserved (Recommended)
| Item | Monthly |
|---|---|
| Compute (D2s v3, 1-Year RI) | $102.67 |
| Storage 30 GiB | $5.01 |
| Backup (LRS) | $0.00 |
| Total | $107.68 |
| Annual | $1,292 |
| Savings vs Plan A | $590/year (31%) |
Plan C: General Purpose Dsv3 — 3-Year Reserved
| Item | Monthly |
|---|---|
| Compute (D2s v3, 3-Year RI) | $68.39 |
| Storage 30 GiB | $5.01 |
| Backup (LRS) | $0.00 |
| Total | $73.40 |
| Annual | $881 |
| Savings vs Plan A | $1,001/year (53%) |
5. Storage Growth & Expansion Plan
Storage is allocated in tiers (30/64/128/256 GiB). Online expansion with zero downtime.
| Year | Cumulative Data | Storage Tier | Storage Monthly | Storage Annual | YoY Increase |
|---|---|---|---|---|---|
| Year 1 | ~20 GB | 30 GiB | $5.01 | $60 | — |
| Year 2 | ~38 GB | 64 GiB | $10.69 | $128 | +$68 |
| Year 3 | ~56 GB | 64 GiB | $10.69 | $128 | +$0 |
| Year 4 | ~74 GB | 128 GiB | $21.38 | $256 | +$128 |
| Year 5 | ~92 GB | 128 GiB | $21.38 | $256 | +$0 |
6. Five-Year Total Cost of Ownership
Annual Breakdown
| Year | Plan A (Burstable) | Plan B (1-Year RI) | Plan C (3-Year RI) |
|---|---|---|---|
| Year 1 | $1,882 | $1,292 | $881 |
| Year 2 | $1,950 | $1,360 | $949 |
| Year 3 | $1,950 | $1,360 | $949 |
| Year 4 | $2,078 | $1,488 | $1,077 |
| Year 5 | $2,078 | $1,488 | $1,077 |
| 5-Year Total | $9,938 | $6,988 | $4,933 |
| 5-Year Savings | — | $2,950 (30%) | $5,005 (50%) |
Cross-Cloud Network Cost (Supplementary)
Oracle Cloud VM ↔ Azure PostgreSQL outbound traffic:
| Item | Estimate |
|---|---|
| Monthly outbound | ~30–50 GB |
| Monthly cost | $3–5 |
| Annual cost | ~$50–60 |
| 5-Year cost | ~$250–300 |
Network cost is negligible relative to compute and storage.
5-Year Grand Total (Including Network)
| Plan | 5-Year Total |
|---|---|
| Plan A (Burstable, pay-as-you-go) | ~$10,200 |
| Plan B (Dsv3, 1-Year RI) | ~$7,300 |
| Plan C (Dsv3, 3-Year RI) | ~$5,200 |
7. Scaling Triggers
| Signal | Action |
|---|---|
| CPU sustained >70% | Upgrade to D4s v3 (4 vCores) |
| Memory sustained >80% | Upgrade to D4s v3 (16 GB RAM) |
| Storage at 80% capacity | Online expansion to next tier |
| Table exceeds 50M rows | Implement table partitioning |
| Devices grow from 17 to 50+ | Consider D4s v3 or higher |
All upgrades can be performed online without downtime.
8. Cost Optimization Recommendations
- Start with pay-as-you-go to validate the migration, then purchase 1-Year Reserved Instance immediately after confirmation.
- Implement table partitioning on
data_dust_rangeranddata_heatmapby Year 2 (~40 GB) to maintain query performance and enable efficient archival. - Archive cold data (>2 years old) to Azure Blob Storage Cool tier at $0.01/GB/month to keep the active database within 64 GiB.
- Enable PgBouncer connection pooling in transaction mode to minimize cross-cloud connection overhead.
- Monitor with Azure Metrics — set alerts on CPU, memory, storage, and connection count to trigger scaling decisions proactively.
9. Recommendation
Plan B (General Purpose Dsv3, 1-Year Reserved) offers the best balance of cost savings and flexibility:
- Base monthly cost: $107.68
- 31% cheaper than Burstable pay-as-you-go
- Annual commitment allows re-evaluation each year
- General Purpose tier provides consistent performance (no burst credit dependency)
- Can switch to 3-Year Reserved after the first year if long-term commitment is confirmed
For organizations certain of 3+ year usage, Plan C reduces the 5-year total cost to approximately $5,200 USD.