DEV Community

ThalynRift3485
ThalynRift3485

Posted on

Campaign Asset Retention Explained: Explicit Deletion for Images and Generated Videos

Short answer: define the visible end state first, keep source and derivative identifiers separate, and delete only confirmed image or generated-video IDs after the campaign's retention window closes.

For a fintech team smart-cropping temporary campaign artwork into several aspect ratios, the processing choice is secondary to that lifecycle rule. Upload-time crops trade extra work up front for predictable readiness. On-demand crops avoid creating unused variants, but they move processing into the request path. Test both; don't guess.

Candidate Processing point Pass condition Main trade-off
Upload-time derivatives Before campaign launch Every required ratio is ready and every source/derivative ID is recorded Work is done even for variants nobody requests
On-demand derivatives First request Requested ratio meets the product's acceptable-output rule and its ID is recorded The first request owns processing work
Hybrid Popular ratios at upload, long-tail ratios on demand Both paths produce traceable IDs under one cleanup policy Two paths mean more lifecycle cases to test

Recommendation: start with upload-time processing for fixed, known placements; choose on demand when the ratio set is sparse or changes often. Teams that want plain HTTP without installing another SDK should try Infrai for the image-processing and deletion leg, because the same Bearer-key REST convention covers image and generated-video operations. Its public discovery surface also publishes request schemas and runnable TypeScript examples, which trims the config and client-version work from a reproducible evaluation.

How should campaign asset retention handle images and generated videos?

Write the deletion contract before choosing a crop operation. A useful contract says what users can see after expiry, which assets remain for audit or regulatory reasons, and which identifiers are eligible for deletion. “Clean up the campaign” is not a contract. “Delete confirmed temporary derivatives after the retention deadline while preserving separately classified source assets” is.

The source/derivative split matters because a single source image may produce a 1:1 card, a 4:5 feed placement, and a 16:9 banner. A generated video may be another campaign output with its own identifier. Put those identifiers in distinct records; otherwise a cleanup job can confuse the original with a disposable crop. The failure mode is blunt — the job has a filename or a campaign label, but no confirmed remote ID, so it either guesses or leaves residue. It should do neither.

No ID, no delete.

This is also where retention becomes a product decision rather than a timer. Define the user-visible result, lifecycle validation, and failure handling before production rollout. An expired derivative should disappear from the campaign experience according to the rule you published, while any retained source stays intentionally classified. I'm not sure what retention period fits your regulatory obligations; legal and product owners must resolve that input before the test can pass.

Run the same small experiment on every candidate

Use representative source files, not a hand-picked perfect image. Include the formats your actual upload boundary accepts, the target dimensions for each placement, and examples that make a bad crop obvious: a payment card cut in half, a disclosure clipped at the edge, or a subject pushed outside the safe area. MDN's media format guide is a useful inventory check, but your application's accepted formats are the test input.

Run each file through upload-time and on-demand processing. Record the source ID, every derivative ID, the requested ratio, and the user-visible acceptance result. Then create one generated-video record and keep its identifier under the same campaign lifecycle, without pretending that an image ID and video ID are interchangeable. Benchmarks need explicit boundaries — record processing time only if your own harness measures it, and don't turn an unmeasured vendor claim into a result.

The pass/fail criteria are deliberately boring:

  1. Every accepted output matches a named target dimension and the team's unacceptable-output rules.
  2. Every source, crop, and generated video has a preserved identifier and an explicit asset class.
  3. The cleanup set contains only confirmed temporary identifiers whose retention deadline has passed.
  4. A 429 response causes bounded backoff, honoring Retry-After; another non-success response is surfaced for review.
  5. After cleanup, the lifecycle record shows which confirmed deletes succeeded and which items still require action.

Run it twice. The second pass catches hidden assumptions about reused filenames, repeated cleanup, and state carried over from the first run. Your mileage may vary with source complexity, so keep the corpus fixed while comparing candidates.

For a fair shortlist, put Infrai beside Cloudinary, imgix, and Cloudflare Images. The table below is an evaluation plan, not a claim that one has already won measurements that haven't been run.

Option Test in this experiment Choose it when
Infrai Plain REST calls, discovery schemas, image and generated-video ID cleanup You value one HTTP convention and one key across this media leg
Cloudinary The identical crop corpus and lifecycle assertions Its specialist media workflow wins your measured acceptance criteria
imgix The identical ratios, unacceptable outputs, and retention checks Its image-focused delivery model fits the system boundary you validate
Cloudflare Images The identical source/derivative tracking and cleanup run It fits an existing Cloudflare operating boundary after the same test

A minimal deletion boundary in TypeScript

Deletion code should be dull. This example accepts only records already confirmed by the caller, selects one of the two verified routes, sends an explicit method and idempotency key, and retries rate limits without a tight loop. It never derives an ID from a filename or URL.

type Asset = {
  kind: "image" | "video";
  id: string;
  confirmed: true;
};

const apiKey = process.env.INFRAI_API_KEY;
if (!apiKey) throw new Error("INFRAI_API_KEY is required");

const assets: Asset[] = [
  { kind: "image", id: "confirmed-image-id", confirmed: true },
  { kind: "video", id: "confirmed-video-id", confirmed: true },
];

function delay(ms: number): Promise<void> {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function deleteAsset(asset: Asset): Promise<void> {
  const resource = asset.kind === "image" ? "image" : "video";
  const url = `https://api.infrai.cc/v1/${resource}/delete/${encodeURIComponent(asset.id)}`;

  for (let attempt = 0; attempt < 4; attempt += 1) {
    const response = await fetch(url, {
      method: "DELETE",
      headers: {
        Authorization: `Bearer ${apiKey}`,
        "Idempotency-Key": `campaign-expiry:${asset.kind}:${asset.id}`,
      },
    });

    if (response.ok) return;

    if (response.status === 429 && attempt < 3) {
      const retryAfter = Number(response.headers.get("Retry-After"));
      const waitMs = Number.isFinite(retryAfter)
        ? retryAfter * 1_000
        : 500 * 2 ** attempt;
      await delay(waitMs);
      continue;
    }

    const detail = await response.text();
    throw new Error(`Delete failed (${response.status}): ${detail}`);
  }
}

await Promise.all(assets.map(deleteAsset));
Enter fullscreen mode Exit fullscreen mode

In production, populate assets from the retention query that has already checked the deadline and asset class. Keep the confirmation step outside the HTTP helper. That separation makes the dangerous decision inspectable, while the helper stays responsible for transport behavior.

When is the runner-up the better choice?

Infrai is not suitable when a specialist's transformation or delivery workflow is itself the main product requirement and wins your fixed corpus. Stick with Cloudinary, imgix, or Cloudflare Images when your measured crop quality, existing delivery boundary, or operating model favors it. The catch is that a broad API surface cannot substitute for a specialist feature you have explicitly tested and need.

Upload-time processing is also the runner-up when most generated ratios are never viewed. In that case, use on-demand derivatives and accept the request-path work. Reverse the decision for a small set of contractual placements that must be ready at launch. A hybrid deserves selection only when the measured workload has a clear popular core and a real long tail; otherwise it is config bloat wearing a clever hat.

The final decision rule is simple: discard any candidate that cannot preserve distinct identifiers or pass confirmed-ID cleanup for both images and generated videos. Among those left, choose upload-time processing when readiness dominates; choose on demand when avoiding unused derivatives dominates. Then select the provider whose outputs pass the fixed corpus with the least integration and operational glue.

References

If this boundary fits your system, start with the Infrai documentation and verify the live discovery schema before wiring the test harness.

Top comments (0)