Cloudflare KV Namespace Setup for API Gateway
This guide covers the one-time setup of Cloudflare KV (Key-Value) namespaces required for the API Gateway caching layer.
What is KV Used For?
The API Gateway (apps/api) uses Cloudflare KV for:
- API Key Validation Cache: Reduces database lookups (5-minute TTL)
- Rate Limiting: Per-user daily quotas with automatic midnight UTC expiry
- Plan Limits Cache: User subscription tier limits (1-hour TTL)
This keeps the API fast and stays within Cloudflare's free tier (100K reads, 1K writes/day).
Prerequisites
- Cloudflare account with Workers enabled
wranglerCLI installed- Authenticated with Cloudflare:
wrangler login
Step 1: Create KV Namespaces
You need two namespaces: one for sandbox, one for production.
# Navigate to API directory
cd apps/api
# Authenticate if not already
wrangler login
# Create SANDBOX namespace
wrangler kv:namespace create "FAIHT_CACHE" --env sandbox
# Output example:
# 🌀 Creating namespace with title "faiht-api-sandbox-FAIHT_CACHE"
# ✨ Success!
# Add the following to your configuration file in your kv_namespaces array:
# { binding = "FAIHT_CACHE", id = "abc123def456..." }
# Create PRODUCTION namespace
wrangler kv:namespace create "FAIHT_CACHE"
# Output example:
# 🌀 Creating namespace with title "faiht-api-FAIHT_CACHE"
# ✨ Success!
# Add the following to your configuration file in your kv_namespaces array:
# { binding = "FAIHT_CACHE", id = "xyz789ghi012..." }
Important: Copy both namespace IDs from the output. You'll need them in the next steps.
Step 2: Verify Namespace Creation
# List all KV namespaces
wrangler kv:namespace list
# You should see:
# [
# {
# "id": "abc123def456...",
# "title": "faiht-api-sandbox-FAIHT_CACHE",
# "supports_url_encoding": true
# },
# {
# "id": "xyz789ghi012...",
# "title": "faiht-api-FAIHT_CACHE",
# "supports_url_encoding": true
# }
# ]
Step 3: Configure wrangler.toml (Local Development)
For local development only, you can add the namespace ID directly to wrangler.toml:
# apps/api/wrangler.toml
name = "faiht-api"
main = "src/index.ts"
compatibility_date = "2024-04-01"
[[kv_namespaces]]
binding = "FAIHT_CACHE"
id = "abc123def456..." # Use sandbox ID for local dev
[vars]
SUPABASE_URL = "http://127.0.0.1:54321"
[!WARNING] > DO NOT commit real namespace IDs to Git!
The current placeholder (
id = "placeholder") is intentional. The GitHub Actions workflow will replace it at deployment time using thesedcommand.
Step 4: Add to GitHub Secrets
The CI/CD workflow needs these namespace IDs as GitHub Secrets:
Via GitHub Web UI
- Go to: Repository → Settings → Secrets and variables → Actions → Secrets
- Click New repository secret
- Add:
- Name:
SANDBOX_KV_NAMESPACE_IDValue:abc123def456...(sandbox namespace ID from Step 1) - Name:
PROD_KV_NAMESPACE_IDValue:xyz789ghi012...(production namespace ID from Step 1)
- Name:
Via GitHub CLI
# From repository root
gh secret set SANDBOX_KV_NAMESPACE_ID --body "abc123def456..."
gh secret set PROD_KV_NAMESPACE_ID --body "xyz789ghi012..."
# Verify
gh secret list | grep KV
Step 5: Test KV Access Locally
Create a test script to verify KV works:
cd apps/api
# Start local dev server
wrangler dev
# In another terminal, test KV
curl http://localhost:8787/v1/health
Or test directly via wrangler:
# Write a test key
wrangler kv:key put --binding=FAIHT_CACHE "test-key" "test-value" --env sandbox
# Read the key
wrangler kv:key get --binding=FAIHT_CACHE "test-key" --env sandbox
# Output: test-value
# Delete the key
wrangler kv:key delete --binding=FAIHT_CACHE "test-key" --env sandbox
Step 6: Deployment Workflow Integration
The GitHub Actions workflow (.github/workflows/_cloudflare_worker.yml) automatically:
- Retrieves the namespace ID from GitHub Secrets
- Updates
wrangler.tomlwith the correct ID - Deploys the worker with KV binding
No manual configuration needed once secrets are set.
Verification
After deployment, verify KV is working:
# Check API health (includes KV check)
curl https://api.freeaihashtags.com/v1/health
# Expected response:
# {"status":"ok","kv":"connected"}
KV Usage Limits (Free Tier)
| Operation | Free Tier Limit | Current Usage Pattern |
|---|---|---|
| Reads | 100,000/day | ~50K/day (API key lookups) |
| Writes | 1,000/day | ~200/day (rate limit updates) |
| Storage | 1 GB | <1 MB (ephemeral cache) |
Estimated Cost: $0/month (well within free tier)
Troubleshooting
Error: "KV namespace not found"
Cause: Worker deployed without KV binding
Fix:
# Verify namespace exists
wrangler kv:namespace list
# Re-deploy with correct binding
cd apps/api
wrangler deploy
Error: "Binding FAIHT_CACHE not defined"
Cause: wrangler.toml missing KV namespace configuration
Fix: Check that [[kv_namespaces]] section exists in wrangler.toml
GitHub Actions: "sed: no input files"
Cause: Workflow running from wrong directory
Fix: Ensure working-directory: apps/api is set in workflow
Cleanup (If Needed)
To delete a namespace (WARNING: irreversible):
# Delete sandbox namespace
wrangler kv:namespace delete --namespace-id "abc123def456..."
# Delete production namespace
wrangler kv:namespace delete --namespace-id "xyz789ghi012..."