Purge Reference
January 20, 2026 ยท View on GitHub
The purge module provides cache invalidation by surrogate key.
Functions
purge
pub fn purge(surrogate_key: []const u8) !void
Hard purge cached content by surrogate key. Immediately removes content from cache.
const purge = zigly.purge;
try purge.purge("product-123");
softPurge
pub fn softPurge(surrogate_key: []const u8) !void
Soft purge by surrogate key. Marks content as stale but continues serving it while revalidating.
try purge.softPurge("product-123");
purgeSurrogateKey
pub fn purgeSurrogateKey(surrogate_key: []const u8, options: PurgeOptions) !void
Purge with options.
// Hard purge (default)
try purge.purgeSurrogateKey("key", .{});
// Soft purge
try purge.purgeSurrogateKey("key", .{ .soft_purge = true });
PurgeOptions
pub const PurgeOptions = struct {
soft_purge: bool = false, // If true, mark as stale instead of removing
};
Surrogate Keys
Surrogate keys are tags assigned to cached content. When caching, add surrogate keys:
const cache = zigly.cache;
var body = try cache.insert("product-page-123", .{
.max_age_ns = cache.secondsToNs(3600),
.surrogate_keys = "product-123 category-electronics all-products",
});
Multiple keys are space-separated. You can then purge by any of those keys:
try purge.purge("product-123"); // Purges this product
try purge.purge("category-electronics"); // Purges all electronics
try purge.purge("all-products"); // Purges everything
Hard vs Soft Purge
Hard Purge
try purge.purge("product-123");
- Immediately removes content from cache
- Next request fetches fresh content from origin
- May cause origin load spike if many requests hit at once
Soft Purge
try purge.softPurge("product-123");
- Marks content as stale
- Continues serving stale content while one request revalidates
- Reduces origin load
- Best for content that changes frequently
Example Usage
API-Triggered Purge
const std = @import("std");
const zigly = @import("zigly");
const purge = zigly.purge;
fn start() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
var downstream = try zigly.downstream();
var uri_buf: [4096]u8 = undefined;
const uri = try downstream.request.getUriString(&uri_buf);
// Purge API endpoint
if (std.mem.startsWith(u8, uri, "/api/purge/")) {
// Authenticate (check API key, etc.)
const api_key = downstream.request.headers.get(allocator, "X-API-Key") catch "";
if (!std.mem.eql(u8, api_key, "secret-key")) {
try downstream.response.setStatus(401);
try downstream.response.finish();
return;
}
// Extract surrogate key from path
const key = uri["/api/purge/".len..];
// Purge
try purge.softPurge(key);
try downstream.response.setStatus(200);
try downstream.response.body.writeAll("Purged");
try downstream.response.finish();
return;
}
try downstream.proxy("origin", null);
}
Content Update Purge
fn updateProduct(product_id: []const u8, new_data: []const u8) !void {
// Update in backend/database
var req = try Request.new("PUT", "/api/products");
try req.body.writeAll(new_data);
var resp = try req.send("api_backend");
try resp.close();
// Purge cached pages
var key_buf: [64]u8 = undefined;
const key = try std.fmt.bufPrint(&key_buf, "product-{s}", .{product_id});
try purge.softPurge(key);
}
Batch Purge
fn purgeMultipleKeys(keys: []const []const u8) !void {
for (keys) |key| {
purge.softPurge(key) catch |err| {
std.debug.print("Failed to purge {s}: {}\n", .{ key, err });
};
}
}
// Usage
try purgeMultipleKeys(&[_][]const u8{
"product-123",
"product-456",
"category-electronics",
});
Request-Level Cache Control
You can also control caching per-request:
fn start() !void {
var downstream = try zigly.downstream();
// Set surrogate key for this request's cached response
try downstream.request.setCachingPolicy(.{
.ttl = 3600,
.surrogate_key = "my-content-key",
});
try downstream.proxy("origin", null);
}
Notes
- Purges propagate across all Fastly edge servers
- Purge operations are rate-limited
- Use soft purge when possible to reduce origin load
- Surrogate keys are case-sensitive
- Maximum surrogate key length: 1024 characters