Skip to main content

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
  • wrangler CLI 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 the sed command.


Step 4: Add to GitHub Secrets​

The CI/CD workflow needs these namespace IDs as GitHub Secrets:

Via GitHub Web UI​

  1. Go to: Repository → Settings → Secrets and variables → Actions → Secrets
  2. Click New repository secret
  3. Add:
    • Name: SANDBOX_KV_NAMESPACE_ID Value: abc123def456... (sandbox namespace ID from Step 1)
    • Name: PROD_KV_NAMESPACE_ID Value: xyz789ghi012... (production namespace ID from Step 1)

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:

  1. Retrieves the namespace ID from GitHub Secrets
  2. Updates wrangler.toml with the correct ID
  3. 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)​

OperationFree Tier LimitCurrent Usage Pattern
Reads100,000/day~50K/day (API key lookups)
Writes1,000/day~200/day (rate limit updates)
Storage1 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..."