StackPractices
intermediate By Mathias Paulenko

Capacity Planning Forecast Template

A structured template for forecasting infrastructure growth, identifying resource bottlenecks, and planning capacity before traffic surges cause outages.

Overview

Traffic grows, but infrastructure doesn’t grow by itself. Most outages aren’t caused by bad code — they’re caused by systems hitting a wall nobody measured. Capacity planning is the discipline of looking ahead: how much traffic will we have in six months, which resource runs out first, and what does it cost to stay ahead of demand? A capacity forecast turns panic-driven scaling into a scheduled, budgeted, tested operation.

This template is the document side of that discipline — a fillable forecast you can drop into your wiki and review quarterly. It covers the full cycle: measuring today’s utilization, projecting growth, identifying the first bottleneck, planning the scaling work, pricing it, and scheduling the next review. For the broader methodology, the capacity planning guide covers the concepts in depth.

When to Use

Use this template when:

  • You’re entering a growth phase (marketing campaign, product launch, seasonal spike)
  • A service is approaching 60-70% utilization of any critical resource
  • You need to justify infrastructure spending to finance or leadership
  • You want to move from reactive scaling to proactive planning
  • You’re evaluating a move from vertical to horizontal scaling

When not to use it: a brand-new service with no traffic history can’t be forecast — run a load test first (the load test execution plan template fits that job) and come back once you have a few months of baseline data. The same applies after a major architecture change: a migration to a new database or a move to Kubernetes resets the baseline, and the old trend lines stop meaning anything.

Prerequisites

Before creating a capacity forecast:

  • Baseline metrics exist: CPU, memory, disk I/O, network throughput, request rate, latency
  • Historical traffic data is available for at least the last three months
  • Growth assumptions are documented (marketing plans, user acquisition targets, feature launches)
  • Cost data is available: cloud provider bills, reserved instance pricing, licensing
  • The team agrees on what “full” means (80%? 90%? 100% with headroom?)

That last checkbox is the one teams skip, and it’s the one that matters most. “Full” for a database (70% CPU before queries degrade) is very different from “full” for a stateless web tier (90%+ is fine). Write the threshold down per resource or the forecast has no trigger line.

Solution

# Capacity Planning Forecast: `<System / Service>`

> Author: ______ | Date: ______ | Review date: ______
> Service owner: ______ | Team: ______ | Forecast horizon: ______

## 1. Current State

| Metric | Current | Peak (last 30d) | Limit | Headroom |
|--------|---------|-----------------|-------|----------|
| Requests / sec | ______ | ______ | ______ | ______ |
| CPU utilization (%) | ______ | ______ | ______ | ______ |
| Memory utilization (%) | ______ | ______ | ______ | ______ |
| Disk I/O (MB/s or IOPS) | ______ | ______ | ______ | ______ |
| Network throughput (Gbps) | ______ | ______ | ______ | ______ |
| Database connections | ______ | ______ | ______ | ______ |
| Storage used (GB) | ______ | ______ | ______ | ______ |
| Queue depth / backlog | ______ | ______ | ______ | ______ |

**Current infrastructure:**
- ______ instances at ______ size
- ______ databases at ______ tier
- ______ cache nodes
- ______ load balancers
- Estimated monthly cost: ______

## 2. Growth Assumptions

| Driver | Expected Change | Timeframe | Confidence |
|--------|-----------------|-----------|------------|
| ______ | ______ | ______ | High / Medium / Low |
| ______ | ______ | ______ | High / Medium / Low |
| ______ | ______ | ______ | High / Medium / Low |

**Key assumptions:**
- [ ] ______
- [ ] ______

## 3. Traffic Projections

| Period | Projected RPS | Projected MAU | Growth Rate |
|--------|---------------|---------------|-------------|
| Current | ______ | ______ | — |
| +3 months | ______ | ______ | ______ |
| +6 months | ______ | ______ | ______ |
| +12 months | ______ | ______ | ______ |

## 4. Resource Forecast

| Resource | Current | +3m | +6m | +12m | First to Hit Limit? |
|----------|---------|-----|-----|------|---------------------|
| CPU | ______ | ______ | ______ | ______ | Yes / No |
| Memory | ______ | ______ | ______ | ______ | Yes / No |
| Disk I/O | ______ | ______ | ______ | ______ | Yes / No |
| Network | ______ | ______ | ______ | ______ | Yes / No |
| DB connections | ______ | ______ | ______ | ______ | Yes / No |
| Storage | ______ | ______ | ______ | ______ | Yes / No |

## 5. Scaling Plan

### Short Term (0-3 months)
- [ ] ______
- [ ] ______

### Medium Term (3-6 months)
- [ ] ______
- [ ] ______

### Long Term (6-12 months)
- [ ] ______
- [ ] ______

## 6. Cost Projection

| Scenario | Monthly Cost | Annual Cost | Notes |
|----------|-------------|-------------|-------|
| Do nothing | ______ | ______ | Risk of outage |
| Minimum viable | ______ | ______ | Just ahead of demand |
| Comfortable headroom | ______ | ______ | 30-40% buffer |

## 7. Risk Assessment

| Risk | Likelihood | Impact | Mitigation |
|------|------------|--------|------------|
| Growth exceeds forecast | ______ | ______ | ______ |
| Cloud provider limits | ______ | ______ | ______ |
| Scaling takes longer than expected | ______ | ______ | ______ |
| Budget not approved | ______ | ______ | ______ |

## 8. Action Items

| Task | Owner | Due Date | Status |
|------|-------|----------|--------|
| ______ | ______ | ______ | ______ |

## 9. Appendix

- Links to dashboards: ______
- Historical incident data: ______
- Related ADRs or design docs: ______

How the Forecast Works

A capacity forecast answers three questions, and the template’s sections map to them one to one:

  1. Where are we now? — current utilization against limits (sections 1–2)
  2. Where are we going? — traffic and resource projections (sections 3–4)
  3. What do we do about it? — scaling plan, budget, risk, action items (sections 5–8)

The math underneath is simpler than the discipline around it. Three formulas do most of the work:

  • Growth rate: fit the last 3–6 months of a metric to a trend — compound monthly growth is (end / start)^(1/months) - 1. If the last quarter shows RPS going 800 → 900 → 1,000, that’s roughly 12% monthly growth, not the 8% your user count grew.
  • Runway: runway_months = (limit - current_peak) / monthly_growth. A connection pool at 82/100 growing 8 connections a month has about two months of runway — that number is the deadline everything else works backward from.
  • Headroom target: how much spare capacity you keep above projected peak. Stateless web tiers often run fine at 30% headroom; databases and anything with a hard ceiling (connection pools, disk) deserve 40–50% because they degrade before they fail.

Pull the numbers from systems you already trust: utilization from your monitoring stack, request rates from the load balancer or ingress logs, storage growth from disk metrics rather than database row counts, and cost from the actual provider bill rather than the pricing calculator — the bill includes egress and all the line items the calculator forgets. If a metric isn’t measured today, instrument it now and mark the section “insufficient history” rather than guessing; an honest gap is a finding, not a failure.

One modeling choice matters more than any formula: project peaks, not means. Forecast the 95th-percentile busy hour, because that’s the hour the outage happens on. If your monitoring only shows daily averages, multiply by your observed peak-to-average ratio — for most web services it sits between 1.5x and 3x.

Two more modeling details separate a forecast that works from one that only looks plausible:

  • Not everything grows linearly with traffic. Storage grows with data volume, not requests — a feature that logs more per request doubles your storage slope without touching RPS. Connection pools grow with concurrent sessions. Cache memory grows with working-set size, which follows catalog size, not traffic. Give each resource its own driver where the obvious one doesn’t apply.
  • Build three scenarios, not one line. Expected growth, high growth (the marketing campaign lands big), and low growth (it flops). Each scenario gets its own bottleneck date. The base plan follows “expected,” but your action triggers should reference “high” — if the high scenario puts the disk over its limit in October, you start the procurement conversation in August, not when the disk is full.

It also helps to separate three kinds of demand that often get blended into one growth number. Organic demand is the baseline trend — users and usage growing steadily. Event-driven demand is everything with a date attached: launches, campaigns, seasonal peaks, a big customer’s onboarding. Structural demand is growth caused by what you ship rather than who arrives — a new feature that doubles data written per request grows your storage forecast without changing traffic at all. Model each separately, then add them. The classic forecasting failure is treating a launch spike as organic growth (you over-provision forever) or treating organic growth as a spike (you under-provision exactly when it matters).

The seasonal overlay deserves the same treatment. If your traffic has a 2.5x holiday multiplier, apply it on top of the growth trend — a 12% monthly growth line that hits 80% CPU in December becomes a real emergency at 2.5x in November. The example dashboard below does exactly this: every “OVER” row in November–January is the seasonal multiplier landing on top of organic growth.

How to Fill It In

Fill the template in order — each section feeds the next.

Section 1 (Current State) comes straight from your monitoring. Use peak values from the last 30 days, not averages — a service averaging 40% CPU can sit at 90% during lunch. The headroom column is the only one that needs judgment: current peak vs. the “full” threshold you agreed on in prerequisites.

Section 2 (Growth Assumptions) is where forecasts die quietly. Every driver gets a confidence level, and low-confidence drivers (an unconfirmed marketing campaign, a tentative partnership) belong in a scenario, not in the base projection. If product can’t tell you expected growth, write down your own number and mark it low confidence — a wrong assumption on record beats an undocumented one.

Section 3 (Traffic Projections) converts drivers into numbers. Work in the unit that drives load — requests per second, not users — because traffic per user drifts. If you can’t justify a number, bracket it: a low/expected/high range is honest, a single confident-looking guess isn’t.

Section 4 (Resource Forecast) applies the traffic growth rate to each resource. This is where the forecast earns its keep: the first resource to hit its limit is your bottleneck, and its deadline is your scaling deadline. Everything else is buffer. Watch for resources that scale non-linearly — connection pools and disk fill on data growth, which usually outpaces request growth.

Section 5 (Scaling Plan) gets concrete: each bottleneck needs an action, an owner, and a start date that lands before its deadline minus lead time. “Add capacity in Q4” isn’t a plan; “increase connection pool to 200 by September 15, because October is when we hit 100” is.

Section 6 (Cost Projection) translates the technical plan into budget language. The “do nothing” row isn’t filler — it’s the price of inaction, and it’s what gets the plan approved. The infrastructure cost allocation template helps when you need per-team or per-service cost breakdowns.

Sections 7–8 close the loop: risks get likelihood and mitigation (the honest answer to “what makes this forecast wrong?”), and every open item gets a named owner and a due date — the two columns that keep the document from dying after week one.

Section 9 (Appendix) looks optional and isn’t. Link the dashboards the numbers came from, the incidents that justify the headroom choices, and the ADRs that constrain the scaling plan. Six months from now, when someone asks why the forecast assumes 40% database headroom, “see incident INC-284 in the appendix” is a better answer than “we picked a number.”

Capacity Forecast Dashboard Example

Here’s what a completed forecast looks like as a dashboard — the projection table flags exactly when each resource crosses its limit:

=== Capacity Forecast Dashboard — Q3 2026 ===

CURRENT STATE (as of 2026-07-11):
  CPU utilization (avg):     42%
  CPU utilization (peak):    68%
  Memory utilization (avg):  55%
  Memory utilization (peak): 78%
  Disk usage:                3.2 TB / 5 TB (64%)
  Network throughput (avg):  120 Mbps
  Network throughput (peak): 450 Mbps
  DB connections (avg):      45 / 100
  DB connections (peak):     82 / 100

GROWTH ASSUMPTIONS:
  User growth rate:          8% / month (based on last 6 months)
  Traffic growth rate:       12% / month (traffic grows faster than users)
  Data growth rate:          50 GB / month
  Seasonal peak factor:      2.5x (Black Friday, holiday season)

6-MONTH PROJECTION:
  Month    | CPU Peak | Mem Peak | Disk    | DB Conn Peak
  ---------|----------|----------|---------|-------------
  Aug 2026 | 72%      | 82%      | 3.7 TB  | 88
  Sep 2026 | 78%      | 86%      | 4.2 TB  | 94
  Oct 2026 | 85%      | 91%      | 4.7 TB  | 102 (OVER!)
  Nov 2026 | 95%      | 96%      | 5.2 TB  | 115 (OVER!)
  Dec 2026 | 98%      | 98%      | 5.7 TB  | 125 (OVER!)
  Jan 2027 | 100%+    | 100%+    | 6.2 TB  | 140 (OVER!)

BOTTLENECK: Database connections hit limit in October 2026
ACTION: Increase connection pool to 200 by September 2026

BOTTLENECK: Disk hits 5 TB limit in November 2026
ACTION: Add 3 TB storage by October 2026

BOTTLENECK: CPU hits 90% in November 2026 (seasonal peak)
ACTION: Add 4 instances to auto-scaling group by October 2026

Read it bottom-up: the bottlenecks at the end are the deliverable. This example shows why averages lie — CPU averages 42% but peaks at 68% today, and the connection pool runs out a month before the disk does. Each bottleneck gets an action with a deadline that’s earlier than the failure date, because procurement and rollout take time.

The Forecast Loop

Capacity planning isn’t a document you write once — it’s a loop. Measure the baseline, project the growth, find the first bottleneck, plan the fix, budget it, then measure again next quarter and compare reality against the forecast.

Capacity planning loop — baseline metrics feed a growth forecast, the forecast exposes the first bottleneck, which drives the scaling plan and budget request, and quarterly review compares actual usage against the projection

The last step is the one most teams skip. Comparing forecast vs. actual is how the model gets calibrated — if traffic grew 8% but you projected 12%, next quarter’s projection adjusts. A forecast that never gets checked against reality stays fiction.

Reviewing the Forecast

The quarterly review is a fifteen-minute meeting, not an audit. Three questions cover it:

  1. Did reality match the projection? Pull actual peaks for each resource and write them next to the forecasted values. A systematic miss in one direction means the growth driver is wrong; random misses mean the horizon is too long.
  2. Did any action item slip? A scaling action that missed its deadline is either a resourcing problem or a forecast that didn’t allocate lead time — fix the cause, not just the task.
  3. What changed since last review? New features, a pricing change, a migration, a big customer signing. Anything that invalidates a growth assumption goes into section 2 of the next version.

Keep the old forecast versions. A folder of dated forecasts — each one annotated with what actually happened — is the cheapest forecasting-accuracy dataset you’ll ever build, and it’s what turns a yearly guessing exercise into a model that converges.

Ownership matters here the same way it matters for monitoring policies: one named owner (usually the SRE or platform lead), the document in version control next to the infrastructure code it describes, and changes reviewed like any other operational artifact. A forecast that lives in a wiki nobody watches is indistinguishable from no forecast at all — except that people keep trusting it.

Variants

ContextAdjustmentsNotes
Database-specificAdd query throughput, index growth, replication lag, and connection pool limitsDatabases hit limits differently than compute
Storage-heavy systemsAdd data retention policies, compression plans, and tiered storage costsStorage grows predictably but is expensive
Event-driven / queue-basedAdd throughput per shard, consumer lag, and dead-letter queue growthQueues hide backpressure until they overflow
Multi-regionAdd cross-region replication bandwidth and per-region capacityEach region may have different growth
ServerlessAdd invocation counts, concurrency limits, and cold-start frequencyServerless limits are different from instance limits

Pick the variant by asking which resource runs out first — that’s the table row that drives your forecast horizon. A database-heavy service plans around the connection pool and replication lag; a queue-based system plans around consumer lag; serverless plans around quota ceilings you can only raise by opening a support ticket weeks ahead.

What Works

  1. Forecast monthly, review quarterly — assumptions change; refresh the forecast before it becomes fiction
  2. Use percentiles, not averages — p99 latency and peak CPU matter more than mean values
  3. Include a “do nothing” scenario — it makes the cost of inaction explicit
  4. Test your scaling plan — run a load test that simulates your 6-month projection before you need it
  5. Share the forecast broadly — product, finance, and engineering should all see the same numbers
  6. Set scaling triggers, not just dates — “add capacity when peak CPU sustains 70% for two weeks” survives a bad forecast better than a calendar date
  7. Track forecast accuracy — record projected vs. actual each quarter so the model converges instead of drifting

Common Mistakes

  1. Planning based on averages — a system at 50% average CPU can be at 95% during peak hours
  2. Ignoring the database — compute scales horizontally; databases often don’t
  3. Forgetting about downstream services — scaling your API is useless if your cache or database can’t keep up
  4. No confidence levels on assumptions — marketing campaigns fail; build scenarios for high, medium, and low growth
  5. Waiting until 90% utilization — by then you’re already in emergency mode; plan at 70%
  6. Forecasting compute but not cost — the budget line is what leadership reads; a technically perfect forecast that gets denied is still a failed plan

Troubleshooting

  • The forecast misses reality by a mile every quarter: your growth driver is wrong, not your math. Recheck whether traffic actually follows the driver you picked (signups ≠ requests; a marketing campaign can double signups while read traffic stays flat).
  • Utilization climbs but the dashboard looks fine: you’re watching averages. Switch the baseline metrics to p95/p99 peaks — averages hide the wall until you hit it.
  • Projected costs came in way under the bill: check data transfer, NAT gateway, and storage growth — egress and storage routinely outgrow the compute forecast.
  • A scaling action slipped past the bottleneck deadline: the lead time assumption was optimistic. Record real procurement/deploy lead times in the appendix and bake them into the next forecast’s action dates.
  • Load test says capacity is fine but production disagrees: the test traffic didn’t match production shape. Real traffic has bursts, retries, and uneven hot keys — replay production traffic or use the load test execution plan template to build a realistic profile.
  • Nobody updated the forecast after launch: assign the document an owner and put the quarterly review on the calendar; an unmaintained forecast is worse than none because people trust it.

Further Reading

Frequently Asked Questions

How far ahead should we forecast?

Twelve months is typical for infrastructure planning, but review quarterly. Beyond 12 months, assumptions become guesses. For high-growth startups, 6 months may be more realistic. The key isn't the horizon — it's the review cadence.

What if we're wrong?

Build contingency into the plan: auto-scaling for unexpected spikes, reserved instances for predictable base load, and a documented emergency scaling runbook. The goal isn't perfect prediction; it's knowing what to do when reality diverges from the forecast.

Who should own capacity planning?

Platform or SRE teams usually own the process, but product and engineering must provide the growth assumptions. Finance should review cost projections. It's a cross-functional document, not a solo exercise.

How do we forecast for seasonal traffic spikes?

Analyze historical traffic for seasonal patterns: holiday shopping, tax season, industry events. Identify the peak multiplier (e.g., 2.5x normal traffic), plan capacity for the peak rather than the average, and pre-scale before the season starts — scaling during the spike is too late. Use reserved instances for the base load and on-demand for the seasonal peak, then scale down afterward and record actual vs. forecast for next year's model.

What's the difference between vertical and horizontal scaling?

Vertical scaling adds resources to existing instances (more CPU, more RAM). It's simpler but has a hard limit — the maximum instance size — and often needs downtime. Horizontal scaling adds more instances; it's more complex (load balancing, stateless services) but has no theoretical limit. Most systems combine both: vertical for databases, horizontal for stateless services.

How do we handle capacity planning for serverless architectures?

Track invocation counts, concurrent executions, and cold-start frequency, and monitor service quotas (AWS Lambda defaults to 1,000 concurrent executions). Forecast on request-rate growth rather than CPU or memory, plan for cold starts during spikes (pre-warm or provisioned concurrency for latency-sensitive paths), and watch cost per invocation — serverless costs can grow super-linearly with traffic.

How do we communicate capacity needs to leadership?

Translate technical metrics into business terms: "At current growth, we run out of database capacity in October. That means slow responses for 30% of users. The fix costs $5,000/month and takes three weeks." Show the cost of inaction next to the cost of action, include a timeline with deadlines, and present the forecast in the regular engineering review — not as an emergency when capacity is already gone.

What tools help with capacity planning?

Cloud provider dashboards (CloudWatch, GCP Monitoring, Azure Monitor) cover current metrics; Datadog or New Relic unify observability; Kubernetes metrics-server and the cluster autoscaler handle containerized workloads; Terraform provisions capacity quickly; AWS Cost Explorer or CloudHealth project costs; Grafana builds custom capacity dashboards. The best tool is the one that integrates with your monitoring and keeps historical data for trend analysis.