# Cost Analysis and Optimization for DR Configurations

**Last updated:** 2026-04
**Status:** GA
**Category:** Business Continuity & Disaster Recovery

---

## Introduksjon

Kostnadsanalyse av BCDR-løsninger for AI-systemer er avgjørende for å sikre at organisasjonen investerer riktig i resiliens. DR-kostnader kan utgjøre alt fra 2% til 100% av primære driftskostnader, avhengig av valgt strategi. For AI-workloads er kostnadene spesielt høye fordi tjenester som Azure OpenAI (Provisioned Throughput), AI Search og GPU-compute er dyre.

Azure Well-Architected Framework anbefaler at DR-kostnad skal stå i proporsjonal sammenheng med forretningsverdien av systemet og konsekvensene av nedetid. Tier 0 (Mission Critical) systemer rettferdiggjør høye DR-kostnader, mens Tier 3 (Administrative) systemer bør minimere kostnadene.

For norsk offentlig sektor krever Utredningsinstruksen at alternative løsninger evalueres med kost/nytte-analyse. BCDR-valg bør dokumenteres med tydelig kostnadssammenligning og forretningsbegrunnelse.

## Total Cost of Ownership-beregning

### TCO-modell for AI BCDR

```python
# TCO-kalkulator for AI DR-konfigurasjon
from dataclasses import dataclass
from typing import Dict

@dataclass
class AIDRCostModel:
    """Calculate Total Cost of Ownership for AI DR configuration."""

    # Primær region kostnader (monthly NOK)
    openai_primary_monthly: float = 0
    search_primary_monthly: float = 0
    cosmos_primary_monthly: float = 0
    app_service_primary_monthly: float = 0
    storage_primary_monthly: float = 0
    networking_primary_monthly: float = 0

    def calculate_dr_cost(self, strategy: str) -> Dict:
        """Calculate DR cost for given strategy."""
        primary_total = sum([
            self.openai_primary_monthly,
            self.search_primary_monthly,
            self.cosmos_primary_monthly,
            self.app_service_primary_monthly,
            self.storage_primary_monthly,
            self.networking_primary_monthly
        ])

        if strategy == "active-active":
            dr_costs = {
                "openai": self.openai_primary_monthly * 1.0,
                "search": self.search_primary_monthly * 1.0,
                "cosmos": self.cosmos_primary_monthly * 0.5,  # Multi-region included
                "app_service": self.app_service_primary_monthly * 1.0,
                "storage": self.storage_primary_monthly * 0.3,  # GRS overhead
                "networking": self.networking_primary_monthly * 0.5,  # Cross-region
                "bandwidth": primary_total * 0.02  # ~2% for replication
            }

        elif strategy == "warm-standby":
            dr_costs = {
                "openai": self.openai_primary_monthly * 0.3,  # Pay-per-token, lower usage
                "search": self.search_primary_monthly * 0.67,  # 2/3 replicas
                "cosmos": self.cosmos_primary_monthly * 0.3,   # Autoscale baseline
                "app_service": self.app_service_primary_monthly * 0.33,  # 1 instance
                "storage": self.storage_primary_monthly * 0.3,
                "networking": self.networking_primary_monthly * 0.2,
                "bandwidth": primary_total * 0.01
            }

        elif strategy == "cold-standby":
            dr_costs = {
                "openai": 0,  # Redeploy on demand
                "search": 0,  # Rebuild on demand
                "cosmos": self.cosmos_primary_monthly * 0.1,  # Backup only
                "app_service": 0,  # Deploy on demand
                "storage": self.storage_primary_monthly * 0.3,  # GRS for data
                "networking": self.networking_primary_monthly * 0.05,
                "bandwidth": primary_total * 0.005
            }

        elif strategy == "backup-restore":
            dr_costs = {
                "openai": 0,
                "search": 0,
                "cosmos": self.cosmos_primary_monthly * 0.05,
                "app_service": 0,
                "storage": self.storage_primary_monthly * 0.15,  # Backup storage
                "networking": 0,
                "bandwidth": 0
            }

        dr_total = sum(dr_costs.values())

        return {
            "strategy": strategy,
            "primary_monthly_nok": round(primary_total),
            "dr_monthly_nok": round(dr_total),
            "total_monthly_nok": round(primary_total + dr_total),
            "dr_percentage": round(dr_total / primary_total * 100, 1),
            "dr_annual_nok": round(dr_total * 12),
            "breakdown": {k: round(v) for k, v in dr_costs.items()}
        }

# Eksempel for typisk norsk offentlig AI-løsning
model = AIDRCostModel(
    openai_primary_monthly=25000,     # GPT-4o, ~500K tokens/dag
    search_primary_monthly=15000,      # Standard S1, 3 replicas
    cosmos_primary_monthly=8000,       # Multi-region, 10K RU/s
    app_service_primary_monthly=12000, # P3v3 x 3
    storage_primary_monthly=3000,      # 1 TB GZRS
    networking_primary_monthly=5000    # Front Door + VNet
)

for strategy in ["active-active", "warm-standby", "cold-standby", "backup-restore"]:
    result = model.calculate_dr_cost(strategy)
    print(f"\n{strategy.upper()}")
    print(f"  DR kostnad: {result['dr_monthly_nok']:,} NOK/mnd ({result['dr_percentage']}%)")
    print(f"  Total: {result['total_monthly_nok']:,} NOK/mnd")
    print(f"  Årlig DR: {result['dr_annual_nok']:,} NOK")
```

### Kostnadsoversikt per strategi

| Komponent | Primær | Active-Active | Warm Standby | Cold Standby | Backup Only |
|-----------|--------|---------------|-------------|-------------|-------------|
| Azure OpenAI | 25,000 | 25,000 | 7,500 | 0 | 0 |
| AI Search | 15,000 | 15,000 | 10,000 | 0 | 0 |
| Cosmos DB | 8,000 | 4,000 | 2,400 | 800 | 400 |
| App Service | 12,000 | 12,000 | 4,000 | 0 | 0 |
| Storage | 3,000 | 900 | 900 | 900 | 450 |
| Networking | 5,000 | 2,500 | 1,000 | 250 | 0 |
| Bandwidth | — | 1,360 | 680 | 340 | 0 |
| **DR total/mnd** | — | **60,760** | **26,480** | **2,290** | **850** |
| **% av primær** | — | **89%** | **39%** | **3%** | **1%** |
| **RTO** | — | ~0 | 5–15 min | 30–60 min | Timer |
| **RPO** | — | ~0 | Minutter | Timer | 24 timer |

*Alle beløp i NOK, estimat for typisk offentlig sektor AI-løsning.*

## RTO/RPO vs. kostnads trade-off analyse

### Beslutningsmatrise

```
Kostnad (NOK/mnd)
  │
  │  Active-Active
  │  ■ (60K)
  │
  │                     Warm Standby
  │                     ■ (26K)
  │
  │
  │
  │                                        Cold Standby
  │                                        ■ (2.3K)
  │                                                   Backup/Restore
  │                                                   ■ (850)
  └─────────────────────────────────────────────────── RTO
    0      5min    15min    30min    1h     4h    24h
```

### Break-even analyse

```markdown
## Når er Active-Active verdt det?

Merkostnad Active-Active vs. Warm Standby:
  60,760 - 26,480 = 34,280 NOK/mnd = 411,360 NOK/år

For at Active-Active skal være verdt det, må kostnaden
av nedetid overstige denne merkostnaden:

  Nedetid-kostnad per hendelse = (RTO_warm - RTO_active) × Kostnad per minutt
  Forventet besparelse = Nedetid-kostnad × Antall hendelser per år

Eksempel:
  - RTO forskjell: 15 min vs. ~0 = 15 min
  - Kostnad per minutt nedetid: 5,000 NOK (tapt produktivitet, omdømme)
  - Antall hendelser per år: 2

  Besparelse = 15 min × 5,000 NOK × 2 = 150,000 NOK/år

  Merkostnad 411,360 > Besparelse 150,000 → Warm Standby er bedre valg

  Break-even: 411,360 / (15 × 5,000) = 5.5 hendelser/år
  → Trenger 6+ hendelser/år for at Active-Active lønner seg
```

## Reserved Capacity vs. On-Demand prising

### Besparelser med Reserved Instances

| Tjeneste | On-Demand/mnd | 1-år RI/mnd | 3-år RI/mnd | Besparelse 1-år | Besparelse 3-år |
|----------|-------------|-------------|-------------|----------------|----------------|
| App Service P3v3 | 12,000 | 7,800 | 5,400 | 35% | 55% |
| AI Search S1 (3 rep) | 15,000 | 9,750 | 6,750 | 35% | 55% |
| Azure OpenAI PTU (50) | 50,000 | 35,000 | — | 30% | — |
| Redis Premium P1 | 4,500 | 3,150 | 2,250 | 30% | 50% |

### RI-strategi for DR

```markdown
## Anbefalte reservasjoner for DR

### Active-Active DR
- RI for ALLE tjenester i begge regioner (full besparelse)
- Anbefaling: 1-år RI minimum, 3-år for stabile workloads

### Warm Standby DR
- RI for baseline-kapasitet i DR-region (lavere tier)
- On-demand for burst/scale-up kapasitet
- Anbefaling: 1-år RI for baseline, on-demand for topper

### Cold Standby DR
- INGEN RI for DR-region (ressurser kjører ikke)
- RI kun for primær region
- Anbefaling: Bruk Azure Savings Plans for fleksibilitet

### Savings Plans alternativ
Azure Savings Plans gir 1-år eller 3-år commitment
med fleksibilitet til å bruke kapasiteten i hvilken som helst
region — ideelt for DR der regionen kan endres.
```

## Cross-region bandwidth-kostnader

### Bandwidth-prising mellom Azure-regioner

| Datatype | Volume/mnd | Pris/GB | Kostnad/mnd |
|----------|-----------|---------|-------------|
| Cosmos DB replikering | 50 GB | Inkludert | 0 |
| Blob Storage GRS | 100 GB | ~0.70 NOK | 70 |
| AI Search index sync | 10 GB | ~0.70 NOK | 7 |
| Application data | 200 GB | ~0.70 NOK | 140 |
| **Total bandwidth** | **360 GB** | — | **~217 NOK** |

*Intra-Europa bandwidth er relativt rimelig. Kostnaden øker betydelig for cross-kontinent replikering.*

### Optimalisering av bandwidth-kostnader

```markdown
## Bandwidth-optimaliseringsstrategier

1. **Komprimering**: Aktiver gzip/brotli for all cross-region trafikk
   - Typisk besparelse: 60–80% på tekstbasert data

2. **Delta-replikering**: Synkroniser kun endringer, ikke full kopi
   - Bruk Azure Blob Storage Change Feed
   - Event-driven sync i stedet for full re-indeksering

3. **Batch vs. real-time**: Batchvise oppdateringer reduserer overhead
   - Samle opp endringer og synkroniser hvert 5. minutt

4. **CDN for statisk innhold**: Bruk Azure CDN for dokumenter
   - Reduserer cross-region trafikk for hyppig leste filer
```

## Kostnadsoptimalisering og Reserved Instances

### Azure Cost Management dashboard

```bash
# Opprett kostnadsrapport for DR-ressurser
az costmanagement export create \
  --name "dr-cost-report" \
  --scope "/subscriptions/{sub}/resourceGroups/rg-ai-dr" \
  --type "ActualCost" \
  --timeframe "MonthToDate" \
  --storage-account "stacostmgmt" \
  --storage-container "cost-reports" \
  --recurrence "Monthly" \
  --recurrence-period '{"from": "2026-01-01", "to": "2026-12-31"}'

# Sett budsjett med varsler
az consumption budget create \
  --budget-name "ai-dr-budget-2026" \
  --amount 400000 \
  --category "Cost" \
  --time-grain "Annually" \
  --time-period '{"Start": "2026-01-01", "End": "2026-12-31"}' \
  --resource-groups "rg-ai-dr" \
  --notifications '{
    "Warning50": {"enabled": true, "operator": "GreaterThan", "threshold": 50,
      "contactEmails": ["platform@org.no"]},
    "Warning80": {"enabled": true, "operator": "GreaterThan", "threshold": 80,
      "contactEmails": ["platform@org.no", "management@org.no"]},
    "Critical100": {"enabled": true, "operator": "GreaterThan", "threshold": 100,
      "contactEmails": ["platform@org.no", "management@org.no", "cto@org.no"]}
  }'
```

### Kvartalsvis kostnadsrapport-mal

```markdown
## BCDR Kostnadsrapport — Q[X] 2026

### Oppsummering
| Kategori | Budsjett | Faktisk | Avvik |
|----------|---------|--------|-------|
| DR infrastruktur | X NOK | X NOK | X% |
| Bandwidth | X NOK | X NOK | X% |
| DR-testing | X NOK | X NOK | X% |
| **Total** | **X NOK** | **X NOK** | **X%** |

### DR-hendelser dette kvartalet
- Antall failover-initieringer: X
- Gjennomsnittlig RTO oppnådd: X min
- Estimert verdi av DR (unngått nedetid): X NOK

### Optimaliseringsmuligheter
1. [Identifisert mulighet med estimert besparelse]
2. [...]

### Anbefalinger
- [Anbefalte endringer med kostnadspåvirkning]
```

## Referanser

- [Optimize your recovery costs](https://learn.microsoft.com/en-us/azure/well-architected/design-guides/disaster-recovery#optimize-your-recovery-costs) — WAF kostnadsoptimalisering for DR
- [Azure Site Recovery pricing](https://azure.microsoft.com/pricing/details/site-recovery/) — Prising for Site Recovery
- [Azure bandwidth pricing](https://azure.microsoft.com/pricing/details/bandwidth/) — Bandwidth-priser mellom regioner
- [Azure pricing calculator](https://azure.microsoft.com/pricing/calculator/) — Generell priskalkulator
- [Microsoft Cost Management](https://learn.microsoft.com/en-us/azure/cost-management-billing/cost-management-billing-overview) — Kostnadsovervåking. Verified (MCP 2026-04).
- [Azure Savings Plans](https://azure.microsoft.com/pricing/purchase-options/azure-saving-plans/) — Flexible reservasjoner (compute savings plans). Verified (MCP 2026-04).

## For Cosmo

- **Bruk denne referansen** når kunden trenger kostnadsestimat for BCDR-løsninger, eller når de skal sammenligne DR-strategier.
- Warm standby er sweet spot for de fleste offentlige AI-løsninger — 25–40% merkostnad for minutter RTO.
- Vis alltid break-even analyse: sammenlign DR-merkostnaden med estimert kostnad ved nedetid for å rettferdiggjøre investeringen. Verified (MCP 2026-04).
- Azure OpenAI: Pay-per-token i DR-region er nesten alltid bedre enn PTU fordi DR-trafikken er lav under normal drift.
- For Utredningsinstruksen: Presenter alltid minimum 3 alternativer (f.eks. cold/warm/active-active) med kost/nytte-vurdering.
