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..."