Core Concepts
BeginnerHow Partikl generates, tracks, and auto-regenerates thumb/index/original for every uploaded file.
Updated Apr 8, 2026
7 min read
4 API refs
Variants
When you upload a file to Partikl, the system runs it through your namespace's active pipeline graph and produces one or more variants — optimized, transformed copies of the original file.
Every namespace has up to three variant kinds per content type:
| Kind | Purpose | Typical output |
|---|---|---|
thumb | Thumbnails, previews, low-res | .webp 400×400, ≤ 20 KB |
index | Delivery-optimized main version | .avif 1920px, ≤ 200 KB |
original | Archived source, optionally encrypted | original format, full size |
Not all kinds are required
Your pipeline defines which variant kinds exist. A namespace with only a resize node produces thumb and index. Adding the original passthrough node creates the third variant.
How variants are created
Upload triggers pipeline
When a file upload completes, the namespace's active workflow is resolved. Each active pipeline produces one variant kind.
Pipeline hash is snapshot
The current pipeline_hash (FNV-1a 64-bit of the pipeline's semantic JSON) is stored on the variant at creation time. This snapshot is the key to detecting stale variants later.
Processing runs asynchronously
The variant transitions through statuses: PROCESSING → READY (or ERROR). You can poll or subscribe to status changes.
Variant is served via CDN
Once READY, the variant URL is available and cached at edge. Format: https://cdn.partikl.io/{namespace}/{photoId}/{kind}.{ext}
Variant statuses
Each variant has one of four statuses at any point in time:
— Pipeline is running. File is being transformed.
— Transformation complete. Variant is available and CDN-cached.
— Pipeline failed. Check the errorCode field for details.
— Pipeline definition changed after this variant was created. Variant still served but stale.
OUTDATED variants are still served
An OUTDATED variant continues to be delivered from CDN while regeneration runs. There is no downtime — the new variant atomically replaces the old one when READY.
Auto-regeneration
This is Partikl's core differentiator. When you modify a pipeline (e.g., change resize dimensions, add an encode node, update encryption), the system:
- Recomputes the pipeline's
pipeline_hash - Compares it against the
pipeline_hashsnapshot on every existing variant for that pipeline - Marks all mismatching variants as
OUTDATED - Queues regeneration jobs in priority order (newest files first)
You don't write a single line of migration code.
pipeline changes → hash changes → variants marked OUTDATED → background regeneration → READY
Pipeline hash is semantic, not structural
Changing a comment in the pipeline JSON does not change the hash. Only semantically meaningful changes (node params, topology, order) trigger regeneration.
Querying variants
variants(photoId: ID!)
Auth requiredFetch all variants for a given photo
Fetch all variants for a photo with their current status
The original variant has url: null when the namespace has encryption enabled. Use the signed URL mutation to get a time-limited access URL.
Real-time status updates
Subscribe to variant status changes instead of polling:
variantStatusChanged(photoId: ID!)
Auth requiredReal-time variant status updates
subscription WatchVariant($photoId: ID!) {
variantStatusChanged(photoId: $photoId) {
variantId
kind
status
url
errorCode
}
}Waiting for all variants
A common pattern — upload, then wait until all variants are READY:
const { photoId } = await client.upload(file, {
namespace: 'dev1',
});
// Waits until thumb + index + original are all READY
// Timeout: 60s by default
const variants = await client.variants.waitForReady(photoId, {
kinds: ['thumb', 'index'],
timeout: 30_000,
});
console.log(variants.thumb.url);
console.log(variants.index.url);Manual regeneration
Force regeneration of specific variants without changing the pipeline:
regenerateVariant(variantId: ID!, force: Boolean)
Auth requiredTrigger manual re-processing of a variant
mutation RegenerateVariant($variantId: ID!) {
regenerateVariant(variantId: $variantId, force: true) {
variantId
status
}
}Variant fields reference
Variant object
variantId
requiredID
Unique variant identifier. Format: {photoId}_{kind}
photoId
requiredID
Parent photo this variant belongs to.
pipelineId
requiredID
The pipeline that created this variant.
pipelineHash
requiredString
FNV-1a 64-bit hash of the pipeline at the time this variant was created. Used to detect OUTDATED variants when pipeline changes.
kind
requiredVariantKind
One of: thumb | index | original
status
requiredVariantStatus
Current status: PROCESSING | READY | OUTDATED | DELETED
url
String
CDN URL. Null if encrypted original or not yet READY.
mimeType
String
Output MIME type (e.g. image/webp, video/mp4).
sizeBytes
Int
File size in bytes. Available once READY.
width
Int
Output width in pixels. Null for audio/file variants.
height
Int
Output height in pixels. Null for audio/file variants.
errorCode
String
Error code if status is ERROR. See error codes reference.
createdAt
requiredDateTime
ISO 8601 timestamp when the variant was created.
updatedAt
requiredDateTime
ISO 8601 timestamp of last status change.
Related
- Processing Lifecycle — full upload-to-ready flow
- Auto-regeneration — how pipeline changes trigger re-processing
- Status Codes Reference — all status values and transitions
- Subscriptions — real-time event streaming
Was this page helpful?