# How I Handle 1M API Requests on $50 Budget

# How I Handle 1 Million API Requests Monthly on Just $50: My Cost-Effective Scaling Journey

I still remember the panic attack I had when my side project suddenly got featured on Product Hunt. Within 24 hours, my API requests skyrocketed from 10,000 to 500,000. My AWS bill? It would've been $847 that month. I had exactly $50 budgeted for infrastructure.

That was two years ago. Today, I'm handling over 1 million API requests monthly, and my infrastructure costs have never exceeded $50. Here's exactly how I did it—and how you can too.

## The Wake-Up Call That Changed Everything

My app, a simple weather aggregation service for developers, was bleeding money. I was using the "default" setup most tutorials recommend: AWS Lambda with API Gateway, a managed PostgreSQL instance, and Redis for caching. Standard stuff, right?

Wrong. For a bootstrapped developer, "standard" meant financial suicide.

The breaking point came when I calculated my cost per 1,000 API requests: **$0.85**. At scale, this was unsustainable. I needed to get that number below **$0.05** without sacrificing reliability or performance.

## My $50 Infrastructure Stack (The Technical Breakdown)

### H2: The Foundation: Choosing the Right Platform

After testing 12 different hosting providers, I landed on a combination that changed everything:

**Primary Stack:**
- **Hetzner Cloud VPS** (CX21): €4.15/month (~$4.50)
- **Cloudflare** (Free tier): $0
- **Supabase** (Free tier): $0
- **Upstash Redis** (Free tier): $0
- **BunnyCDN**: ~$1/month

**Total monthly cost: $5.50** (leaving $44.50 for scaling headroom)

### H2: Architecture That Actually Scales on a Budget

Here's the architecture that handles my 1M+ requests:

```
User Request → Cloudflare (CDN/DDoS) → Nginx (Rate Limiting) 
→ Node.js API (Hetzner VPS) → Redis Cache (Upstash) 
→ PostgreSQL (Supabase) → Response
```

#### H3: The Caching Strategy That Saved Me Thousands

Caching isn't just about speed—it's about survival on a budget. Here's my three-tier caching approach:

**Tier 1: Cloudflare Edge Cache (Hit Rate: 65%)**
```javascript
// Cloudflare Worker snippet
export default {
  async fetch(request, env) {
    const cache = caches.default;
    const cacheKey = new Request(request.url, request);
    
    let response = await cache.match(cacheKey);
    
    if (!response) {
      response = await fetch(request);
      const headers = new Headers(response.headers);
      headers.set('Cache-Control', 'public, max-age=3600');
      response = new Response(response.body, { 
        ...response, 
        headers 
      });
      await cache.put(cacheKey, response.clone());
    }
    
    return response;
  }
};
```

**Tier 2: Redis Application Cache (Hit Rate: 25%)**
```javascript
const redis = require('@upstash/redis');

async function getCachedData(key) {
  const cached = await redis.get(key);
  if (cached) return JSON.parse(cached);
  
  const fresh = await fetchFromDatabase(key);
  await redis.setex(key, 3600, JSON.stringify(fresh));
  return fresh;
}
```

**Tier 3: Database Query (Hit Rate: 10%)**

This strategy means **90% of my requests never hit the database**, dramatically reducing compute costs.

### H2: Cost Breakdown: Where Every Dollar Goes

| Service | Monthly Cost | Requests Handled | Cost per 1K Requests |
|---------|--------------|------------------|---------------------|
| Hetzner VPS | $4.50 | 1,000,000 | $0.0045 |
| BunnyCDN | $1.00 | 650,000 (static) | $0.0015 |
| Cloudflare | $0.00 | 1,000,000 (proxy) | $0.00 |
| Upstash Redis | $0.00 | 250,000 (cache hits) | $0.00 |
| Supabase | $0.00 | 100,000 (DB queries) | $0.00 |
| **Total** | **$5.50** | **1,000,000+** | **$0.0055** |

Compare this to my original AWS setup:

| Service | Monthly Cost | Cost per 1K Requests |
|---------|--------------|---------------------|
| AWS Lambda | $420 | $0.42 |
| API Gateway | $350 | $0.35 |
| RDS PostgreSQL | $45 | $0.045 |
| ElastiCache | $32 | $0.032 |
| **Total** | **$847** | **$0.847** |

**Savings: $841.50/month (99.35% cost reduction)**

### H2: Optimization Techniques That Made the Difference

#### H3: 1. Aggressive Response Compression

```javascript
const compression = require('compression');
app.use(compression({
  level: 6,
  threshold: 1024,
  filter: (req, res) => {
    if (req.headers['x-no-compression']) return false;
    return compression.filter(req, res);
  }
}));
```

**Result:** 70% reduction in bandwidth costs

#### H3: 2. Database Connection Pooling

```javascript
const { Pool } = require('pg');
const pool = new Pool({
  max: 20,
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 2000,
});

// Reuse connections instead of creating new ones
async function query(text, params) {
  const client = await pool.connect();
  try {
    return await client.query(text, params);
  } finally {
    client.release();
  }
}
```

**Result:** 85% reduction in database connection overhead

#### H3: 3. Smart Rate Limiting

Instead of paying for enterprise rate limiting, I implemented token bucket algorithm:

```javascript
const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per windowMs
  standardHeaders: true,
  legacyHeaders: false,
  store: new RedisStore({
    client: redisClient,
    prefix: 'rl:',
  }),
});

app.use('/api/', limiter);
```

**Result:** Prevented abuse, reduced wasted compute by 40%

### H2: Monitoring Without Breaking the Bank

Free monitoring tools I use daily:

- **Uptime monitoring:** UptimeRobot (free tier)
- **Error tracking:** Sentry (free tier, 5K events/month)
- **Analytics:** Plausible (self-hosted on same VPS)
- **Logs:** Loki + Grafana (self-hosted)

```yaml
# docker-compose.yml for monitoring stack
version: '3'
services:
  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana-storage:/var/lib/grafana
  
  loki:
    image: grafana/loki
    ports:
      - "3100:3100"
    command: -config.file=/etc/loki/local-config.yaml
```

## Key Takeaways: Lessons from Handling 1M Requests on $50

- **Cache aggressively, cache everywhere**: 90% cache hit rate is achievable and transforms your cost structure
- **Free tiers are your friend**: Cloudflare, Supabase, and Upstash offer generous free tiers that handle serious traffic
- **VPS > Serverless for consistent traffic**: Once you hit predictable traffic patterns, a $5 VPS outperforms $500 in serverless costs
- **Bandwidth is expensive**: Compression and CDN usage reduced my bandwidth costs by 80%
- **Monitor what matters**: You don't need expensive APM tools—open-source alternatives work perfectly
- **Optimize database queries**: Every query that hits your database costs money; make them count
- **Rate limiting prevents waste**: Protecting against abuse saves more money than you'd think
- **Static assets on CDN**: Never serve images, CSS, or JS from your application server

## Performance Metrics That Matter

After optimization, here's what my API delivers:

| Metric | Value | Industry Standard |
|--------|-------|-------------------|
| Average Response Time | 45ms | 200ms |
| P95 Response Time | 120ms | 500ms |
| Uptime (6 months) | 99.94% | 99.9% |
| Cache Hit Rate | 90% | 60-70% |
| Cost per 1M requests | $5.50 | $500-1000 |

## FAQ: Your Questions About Budget API Scaling

### Q: Won't a single VPS become a bottleneck as I scale?

**A:** Yes, eventually—but not as soon as you think. My single Hetzner CX21 VPS (2 vCPU, 4GB RAM) comfortably handles 1M requests/month with 90% cache hit rate. When I need to scale:

1. First, I'll upgrade to CX31 ($8/month) for 2M-3M requests
2. Then, add a second VPS behind Cloudflare load balancer ($16/month total) for 5M+ requests
3. Only after 10M requests/month would I consider managed services

The key is that aggressive caching means most requests never touch your application server. Even at 5M requests/month, I'd still be under $20/month.

### Q: What happens if my VPS goes down? Isn't this risky?

**A:** I implement multiple safety nets:

- **Cloudflare's "Always Online"** caches entire pages and serves them during outages
- **Automated backups** to Backblaze B2 (costs $0.50/month for 100GB)
- **Health checks** via UptimeRobot ping me instantly if the server goes down
- **Deployment automation** means I can spin up a new VPS and deploy in under 10 minutes

In 18 months, I've had one unplanned outage (Hetzner datacenter issue) lasting 23 minutes. My uptime is still 99.94%—better than when I was on AWS and had misconfigured auto-scaling take down my entire stack for 4 hours.

### Q: How do you handle traffic spikes without auto-scaling?

**A:** This is where the architecture shines:

1. **Cloudflare absorbs the initial spike** with edge caching
2. **Redis cache** handles the next layer without touching the database
3. **Rate limiting** prevents any single user from overwhelming the system
4. **Nginx queuing** gracefully handles bursts up to 10x normal traffic

During my biggest spike (featured on Hacker News), I went from 30K requests/day to 180K requests/day. The VPS CPU usage peaked at 65%. The 90% cache hit rate meant the database barely noticed.

If I consistently hit 80%+ CPU usage, that's my signal to upgrade the VPS tier—a decision I make proactively, not reactively.

## Conclusion: You Don't Need a Fortune to Scale

Two years ago, I thought handling serious API traffic required serious money. I was wrong.

The secret isn't finding cheaper services—it's **architecting for efficiency first**. Every request you can serve from cache is a request that costs you nearly nothing. Every database query you can avoid is money saved. Every static asset served from a CDN instead of your server is bandwidth you don't pay for.

My $50 budget isn't a limitation—it's a forcing function that made me build better software.

Today, my API serves 1.2 million requests monthly. My infrastructure costs $5.50. And I sleep soundly knowing that even if traffic 10x overnight, I have $44.50 of headroom before I need to worry.

The best part? This approach scales. When I hit 10M requests/month, I'll still be spending under $50. The architecture that saves money at small scale is the same architecture that saves money at large scale.

**Start small, cache aggressively, and scale intelligently.** Your bank account will thank you.

---

*Want to see the complete code and infrastructure setup? I've open-sourced my entire stack on GitHub. [Link to your repo]*

*Have questions about implementing this for your API? Drop a comment below—I respond to every single one.*
