Serve headless CMS content from the DNS caching layer. NULL records for up to 64KB. Global TTL, zero origin load, sub-5ms delivery.
Your headless CMS serves content to millions of visitors. Every page load hits your API. CDN helps, but origin is still hammered during cache misses and invalidations. Content over 4KB needs separate blob storage. Previews require separate infrastructure. Updates need cache purges across regions.
ResolveDB publishes CMS content as DNS records. Small content uses TXT records; larger content (up to 64KB) uses NULL records with TCP fallback. Hash-addressed queries (h- prefix) ensure content integrity and enable 7-day immutable caching. Draft previews use NBA pattern for cryptographic access control.
HTML/JSON content stored directly in NULL records. Hash-addressed for immutability. 7-day cache means viral posts served from DNS resolvers worldwide, not your origin.
get.h-a3f2e8c1d4b5a678...posts.myblog.v1.resolvedb.net TYPE=NULLDraft content uses NBA pattern for authenticated access. 60-second TTL ensures editors see updates quickly. Cryptographic namespace binding prevents unauthorized preview access.
get.sig-<sig>-t-<ts>.auth-h-<jwt>.draft-123.preview.myblog.v1.resolvedb.netImage/video metadata (URLs, dimensions, alt text, responsive variants) served via DNS. Actual binaries on CDN. Manifest cached 24 hours; assets have their own cache headers.
get.manifest.hero-image.assets.myblog.v1.resolvedb.net → {"thumb":"...","large":"..."}Each locale is explicit in the query - no Accept-Language header inference. Same query = same result globally. Each locale-hash combo cached independently.
get.locale-es.h-abc123...article.myblog.v1.resolvedb.netEvery publish creates a new content hash. "Latest" pointer (short TTL) redirects to current version. Rollback is instant - update the pointer. Old versions remain accessible forever.
get.latest.my-article.myblog.v1.resolvedb.net → redirect to h-<current-hash>Shared UI tokens (colors, spacing, typography) distributed globally. Version-pinned queries ensure consistent rendering. 7-day cache for versioned tokens.
get.h-tokens2024q4.design.myblog.v1.resolvedb.net → {"primary":"#FF5722"}h- for integrity, sig- for draftsHybrid: Content-Addressed (h-) + NBA (sig-)Public content uses h-<sha256> prefix - client verifies SHA256(response) matches query. Drafts use NBA for cryptographic access control. Combined patterns prevent both cache poisoning and unauthorized preview access.
# Fetch published article by content hash (7-day cache)
dig TXT get.h-a3f2e8c1d4b5a678901234567890abcdef12345678901234567890abcdef12.posts.myblog.v1.resolvedb.net +short
# Large content (>4KB) - use NULL record over TCP
dig +tcp NULL get.h-a3f2e8c1d4b5a678901234567890abcd.article.myblog.v1.resolvedb.net
# Get latest version pointer (follows redirect)
dig TXT get.latest.my-article.posts.myblog.v1.resolvedb.net +short
# Returns redirect to current hash
# Asset manifest
dig TXT get.manifest.hero-image.assets.myblog.v1.resolvedb.net +short
# {"variants":{"thumb":"https://cdn.example/t.webp","large":"https://cdn.example/l.webp"}}from resolvedb import ResolveDB
import hashlib
db = ResolveDB(namespace="myblog")
# Fetch with automatic integrity verification
def fetch_article(slug: str, content_hash: str) -> dict:
"""Fetch article with SHA-256 verification."""
article = db.content.get_by_hash(content_hash)
# SDK verifies automatically, but you can double-check:
actual_hash = hashlib.sha256(article.raw).hexdigest()
if actual_hash != content_hash:
raise ValueError("Content integrity check failed")
return article.data
# Get latest version (follows redirect)
latest = db.content.get_latest("my-article")
print(f"Title: {latest['title']}")
# Localized content
spanish = db.content.get("my-article", locale="es")
# Preview draft (requires auth)
db_auth = ResolveDB(namespace="myblog", tenant_key="preview-key")
draft = db_auth.preview.get("draft-123", auth=jwt_token)import { ResolveDB } from '@resolvedb/client';
import crypto from 'crypto';
const db = new ResolveDB({ namespace: 'myblog' });
// Public content with integrity verification
async function fetchArticle(contentHash: string) {
const article = await db.content.getByHash(contentHash);
// SDK verifies automatically, throws on mismatch
return article;
}
// Get latest version (auto-follows redirect)
const latest = await db.content.getLatest('my-article');
console.log('Title:', latest.title);
// Localized content - explicit locale, no Accept-Language
const spanish = await db.content.get('my-article', { locale: 'es' });
// Preview draft (NBA pattern auto-applied)
const authDb = new ResolveDB({
namespace: 'myblog',
tenantKey: 'preview-key'
});
const draft = await authDb.preview.get('draft-123', { auth: jwtToken });package main
import (
"crypto/sha256"
"encoding/hex"
"github.com/resolvedb/go-client"
)
func main() {
db := resolvedb.New(resolvedb.Config{
Namespace: "myblog",
})
// Fetch with integrity verification
article, _ := db.Content.GetByHash(
"a3f2e8c1d4b5a678901234567890abcdef12345678901234567890abcdef12",
)
// SDK verifies SHA256 automatically
// Get latest version
latest, _ := db.Content.GetLatest("my-article")
fmt.Println("Title:", latest["title"])
// Localized content
spanish, _ := db.Content.Get("my-article", resolvedb.Opts{
Locale: "es",
})
// Preview draft (with auth)
authDb := resolvedb.New(resolvedb.Config{
Namespace: "myblog",
TenantKey: "preview-key",
})
draft, _ := authDb.Preview.Get("draft-123", resolvedb.WithAuth(jwtToken))
}| Feature | ResolveDB | Alternative |
|---|---|---|
| Global caching | DNS layer (free) | CDN required ($$$) |
| Cache invalidation | Hash change = new entry | Purge API calls |
| Content integrity | SHA-256 verified (h-) | Trust the CDN |
| Large content (>4KB) | NULL records (64KB) | Separate blob storage |
| Draft previews | Cryptographic (NBA) | Secret URL or API key |
| Version rollback | Update pointer (instant) | Cache purge (minutes) |
ALWAYS use the h-<sha256> prefix for content queries. The client verifies SHA256(response) matches the queried hash. Any mismatch indicates cache poisoning and should be rejected. The SDK does this automatically.
Use the chunking protocol - fetch manifest first, then retrieve chunks in parallel. Each chunk has its own hash for integrity. Alternatively, store large assets on CDN and serve manifest (URLs, metadata) via DNS.
UDP DNS has no source IP verification - attackers can spoof IPs and trigger 64KB responses to victims (2048x amplification). TCP handshake verifies the client actually wants the response. All compliant resolvers retry over TCP automatically when they receive TC=1 (truncated) response.
Every version is stored by hash and never deleted. To rollback: update the "latest" pointer to the previous hash via API. Within one TTL period (default 5 min for pointers), all readers get the old version. Old hashes remain accessible for audit/recovery.
Drafts use NBA pattern - the query includes a cryptographic signature bound to your namespace. Even with a valid JWT, queries to other namespaces fail mathematically. Enable privacy mode to prevent draft enumeration via error differentiation.
Use explicit locale parameters: get.locale-es.h-<hash>.content... This follows UQRP design principles - same query always returns same result, regardless of Accept-Language headers. Each locale is cached independently.
Create an account and start storing data in under a minute.