Data
KV Store

KV Store

Fast key-value storage for simple data lookups.

Overview

KV Store provides a simple key-value interface for storing and retrieving data. Built on Cloudflare KV, it's optimized for fast reads and global distribution.

When to Use KV

Good for:

  • User preferences and settings
  • Session data and tokens
  • Cache and temporary data
  • Rate limiting counters
  • Feature flags
  • Simple lookups by key

Not ideal for:

  • Complex queries (use Tables instead)
  • Relational data
  • Large data sets requiring search

Namespaces

Data is organized into namespaces. Think of a namespace as a bucket for related keys.

Create Namespace

lux data kv init user-preferences "User preference storage"

List Namespaces

lux data kv list

Key-Value Operations

Set Value

lux data kv set kv_123 "user:456" '{"theme":"dark","language":"en"}'

Get Value

lux data kv get kv_123 "user:456"

Output:

{
  "theme": "dark",
  "language": "en"
}

Delete Key

lux data kv delete-key kv_123 "user:456"

List Keys

lux data kv keys kv_123

Key Naming Conventions

Use prefixes to organize keys:

user:{userId}                    # User data
session:{sessionId}              # Session tokens
ratelimit:{userId}:{action}      # Rate limiting
feature:{featureName}            # Feature flags
cache:{resourceType}:{id}        # Cached data

Examples:

user:cust_abc123
session:sess_xyz789
ratelimit:cust_abc123:api_calls
feature:new_checkout
cache:product:prod_123

Using KV in Flows

Get Value

Use a Code node or custom KV node:

// Access KV value
const preferences = await kv.get(`user:${inputs.userId}`);
return { preferences: JSON.parse(preferences) };

Set Value

// Store KV value
await kv.set(`user:${inputs.userId}`, JSON.stringify({
  theme: inputs.theme,
  language: inputs.language
}));
return { success: true };

Bulk Operations

Set Multiple

lux data kv set-bulk kv_123 '[
  {"key": "user:1", "value": "{\"name\":\"Alice\"}"},
  {"key": "user:2", "value": "{\"name\":\"Bob\"}"}
]'

Delete Multiple

lux data kv delete-bulk kv_123 '["user:1", "user:2"]'

Import/Export

Export to JSON

lux data kv export kv_123 ./backup.json

Import from JSON

lux data kv import kv_123 ./backup.json

JSON format:

{
  "user:1": {"name": "Alice", "theme": "dark"},
  "user:2": {"name": "Bob", "theme": "light"}
}

Common Patterns

User Preferences

// Get with default
const key = `prefs:${userId}`;
const prefs = await kv.get(key) || '{"theme":"light","notifications":true}';
return JSON.parse(prefs);

Rate Limiting

const key = `ratelimit:${userId}:${action}`;
const count = parseInt(await kv.get(key) || '0');
 
if (count >= 100) {
  throw new Error('Rate limit exceeded');
}
 
await kv.set(key, String(count + 1));
// Note: In production, also set TTL to reset after time window

Feature Flags

const enabled = await kv.get(`feature:${featureName}`);
return { enabled: enabled === 'true' };

Caching

const cacheKey = `cache:product:${productId}`;
let product = await kv.get(cacheKey);
 
if (!product) {
  // Fetch from database
  product = await fetchFromDB(productId);
  await kv.set(cacheKey, JSON.stringify(product));
}
 
return JSON.parse(product);

Performance Notes

  • Reads are fast - Globally distributed, low latency
  • Writes are eventually consistent - May take seconds to propagate
  • Keys are limited - Max 512 bytes per key
  • Values are limited - Max 25 MB per value (keep smaller for performance)

Best Practices

  • Use descriptive key prefixes - Makes debugging easier
  • Store JSON - Serialize complex objects
  • Keep values small - Faster reads
  • Use TTL for temporary data - Auto-cleanup
  • Consider consistency - Writes may take time to propagate

See Also: