Edge Cache
Zatabase ships with a built-in edge cache layer powered by Z3Fungi, a distributed caching system with a brain + worker architecture. The edge cache acts as an integrated CDN — content is cached across worker nodes close to your users, reducing latency and offloading origin traffic. No external CDN required.
How It Works
Section titled “How It Works”The edge cache uses a brain + worker architecture:
- Brain: A coordination node that manages cache state, routes requests, tracks worker nodes, handles cache invalidation, and exposes an S3-compatible object API. Runs as a sidecar process alongside
zserver. - Workers: Distributed cache nodes that store and serve cached objects. Anyone can run a worker node and earn ZATA for serving cache traffic. ZATA can be redeemed for USD via your configured payout method. Vultr, Hetzner, and bring-your-own-server are all supported.
When a request hits the cache:
- The brain checks which worker(s) hold the cached object.
- If found (cache hit), the object is served directly from the nearest worker.
- If not found (cache miss), the brain fetches from origin, stores it across workers, and serves the response.
All communication between Zatabase and the brain happens over HTTP on the brain’s internal API port (default 8081). The brain also exposes an S3-compatible API on port 9000 for direct object storage operations.
Enabling the Edge Cache
Section titled “Enabling the Edge Cache”The edge cache is gated behind the cache feature flag on zserver:
# Build with cache supportcargo build --release -p zserver --features v1,cache
# Or include it in the full feature setcargo build --release -p zserver --features fullConfiguration
Section titled “Configuration”Configure the cache connection via environment variables:
| Variable | Default | Description |
|---|---|---|
ZCACHE_BRAIN_URL | (managed) | Z3Fungi brain internal API URL (auto-configured in Zatabase Cloud) |
ZCACHE_BRAIN_S3_URL | (managed) | Z3Fungi brain S3-compatible API URL (auto-configured in Zatabase Cloud) |
ZCACHE_BRAIN_SECRET or BRAIN_SECRET | — | Shared secret for brain authentication. Required. |
ZCACHE_METRICS_INTERVAL | 30 | Seconds between metric polls from the brain |
ZCACHE_TIMEOUT | 10 | HTTP timeout in seconds for brain API calls |
ZCACHE_ENABLED | true | Master switch. When false, all cache operations return graceful no-ops. |
The edge cache is fully managed in Zatabase Cloud. The brain sidecar is automatically provisioned and configured alongside your project — no manual setup required.
On startup, the platform probes the brain’s /health endpoint and logs whether the cache layer is available. If the brain is unreachable, cache operations return 503 Service Unavailable but the rest of the platform continues operating normally.
API Reference
Section titled “API Reference”All endpoints require authentication via JWT Bearer token.
Cluster Status
Section titled “Cluster Status”# Get cluster overviewcurl -s https://your-project.zatabase.io/v1/cache/status \ -H "Authorization: Bearer $ZATABASE_TOKEN" | jqResponse:
{ "brain_healthy": true, "total_nodes": 5, "online_nodes": 4, "total_cache_bytes": 10737418240, "used_cache_bytes": 3221225472, "hit_ratio": 0.847}Node Management
Section titled “Node Management”# List all cache worker nodescurl -s https://your-project.zatabase.io/v1/cache/nodes \ -H "Authorization: Bearer $ZATABASE_TOKEN" | jq
# Register a new worker nodecurl -s -X POST https://your-project.zatabase.io/v1/cache/nodes/register \ -H "Authorization: Bearer $ZATABASE_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "endpoint": "https://worker-1.example.com:9001", "region": "us-east-1", "capacity_bytes": 5368709120 }' | jq
# Get details for a specific nodecurl -s https://your-project.zatabase.io/v1/cache/nodes/$NODE_ID \ -H "Authorization: Bearer $ZATABASE_TOKEN" | jq
# Deregister a worker nodecurl -s -X DELETE https://your-project.zatabase.io/v1/cache/nodes/$NODE_ID \ -H "Authorization: Bearer $ZATABASE_TOKEN"Metrics
Section titled “Metrics”# Aggregated cluster-wide metricscurl -s https://your-project.zatabase.io/v1/cache/metrics \ -H "Authorization: Bearer $ZATABASE_TOKEN" | jqResponse:
{ "total_hits": 1523847, "total_misses": 28541, "hit_ratio": 0.982, "bytes_served": 89743212544, "bytes_stored": 3221225472, "bytes_capacity": 10737418240, "object_count": 45231, "evictions": 1204, "active_nodes": 4, "avg_latency_ms": 2.3, "p95_latency_ms": 8.1, "p99_latency_ms": 15.7, "collected_at": "2026-03-06T12:00:00Z"}# Per-node metricscurl -s https://your-project.zatabase.io/v1/cache/nodes/$NODE_ID/metrics \ -H "Authorization: Bearer $ZATABASE_TOKEN" | jqCache Purge
Section titled “Cache Purge”# Purge cached objects by key patterncurl -s -X POST https://your-project.zatabase.io/v1/cache/purge \ -H "Authorization: Bearer $ZATABASE_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "prefix": "images/", "keys": ["assets/logo.png", "assets/hero.jpg"] }' | jqResponse:
{ "objects_purged": 142, "bytes_freed": 52428800, "nodes_affected": 3}Full Endpoint Table
Section titled “Full Endpoint Table”| Method | Endpoint | Description |
|---|---|---|
GET | /v1/cache/status | Cluster overview (node count, capacity, hit ratio) |
GET | /v1/cache/nodes | List all registered cache worker nodes |
POST | /v1/cache/nodes/register | Register a new cache worker node |
GET | /v1/cache/nodes/:node_id | Get details for a specific node |
DELETE | /v1/cache/nodes/:node_id | Deregister a cache worker node |
GET | /v1/cache/nodes/:node_id/metrics | Per-node cache metrics |
GET | /v1/cache/metrics | Aggregated cluster-wide cache metrics |
POST | /v1/cache/purge | Purge cached objects by key pattern or prefix |
Node Operator Rewards
Section titled “Node Operator Rewards”Anyone can run a Z3Fungi cache worker node and earn ZATA for serving cache traffic. ZATA can be redeemed for USD via your configured payout method. Vultr and Hetzner are supported out of the box; you can also bring your own server. The reward model works as follows:
- Register your node via
POST /v1/cache/nodes/registerwith your node’s endpoint URL, region, and storage capacity. - Serve cache traffic. Your node handles cache hits for objects stored on it.
- Earn ZATA. Per-node metrics are collected at the configured interval (
ZCACHE_METRICS_INTERVAL). Cache hits and bandwidth served by your node are metered, and your account is credited in ZATA at the current rate.
The reward rates align with the cache pricing model — node operators earn a share of the cache hit and bandwidth fees paid by consumers.
Pricing
Section titled “Pricing”Edge cache usage is metered per operation. Current rates are shown in your dashboard and at checkout.
| Operation | Credits per Unit | Equivalent USD |
|---|---|---|
| Cache hit | 0.0001 per hit | $0.001 per 1M hits |
| Cache miss | 0.001 per miss | $0.01 per 1M misses |
| Cache storage | 25,000 per GB-month | $0.25 per GB-month |
| Cache bandwidth (egress) | 9,000 per GB | $0.09 per GB |
Rates shown reflect current pricing and may update periodically. Live rates are always available in your dashboard.
Cache storage and bandwidth use the same rates as regular platform storage and egress. Cache hits are priced at 10x less than cache misses, incentivizing high hit ratios.
SDK Usage
Section titled “SDK Usage”TypeScript
Section titled “TypeScript”import { ZatabaseClient } from '@zatabase/sdk';
const client = new ZatabaseClient({ baseUrl: 'https://your-project.zatabase.io' });
// Get cluster statusconst status = await client.cache.getStatus();console.log(`Hit ratio: ${status.hit_ratio}`);
// List nodesconst nodes = await client.cache.listNodes();
// Register a new nodeconst registration = await client.cache.registerNode({ endpoint: 'https://my-node.example.com:9001', region: 'eu-west-1', capacity_bytes: 10737418240,});
// Get cluster metricsconst metrics = await client.cache.getMetrics();
// Purge objectsconst result = await client.cache.purge({ prefix: 'images/' });Python
Section titled “Python”from zatabase import ZatabaseClient
async with ZatabaseClient(base_url="https://your-project.zatabase.io") as client: # Get cluster status status = await client.cache.get_status() print(f"Hit ratio: {status['hit_ratio']}")
# List nodes nodes = await client.cache.list_nodes()
# Register a new node registration = await client.cache.register_node({ "endpoint": "https://my-node.example.com:9001", "region": "eu-west-1", "capacity_bytes": 10737418240, })
# Get cluster metrics metrics = await client.cache.get_metrics()
# Purge objects result = await client.cache.purge({"prefix": "images/"})