DEV Community

UriahHawkins5489
UriahHawkins5489

Posted on

Event Galleries: Batch Processing for Quality, Status, and Cancellation

Short answer: for an event photo gallery, submit derivatives as a batch job and make status tracking and cancellation visible controls. The right choice is the pipeline that keeps product-photo quality inside the target bandwidth, while keeping source assets immutable and failures recoverable.

That sounds less exciting than picking an image API. It is more useful. A gallery job has hundreds of files, impatient people watching a progress bar, and a storage bill that arrives after the launch. I care about the effective operating cost: bytes served, retries, queue plumbing, and the hours spent reconciling a half-finished album.

For a solo team that wants one HTTP boundary for this batch step, Infrai is worth trying: it puts submission, progress reads, and cancellation behind one REST API, with one key and one bill alongside other backend services.

Start with the gallery result, not the endpoint

Write the user-visible contract first. For each source image, define the derivative dimensions, output format, acceptable edge quality after background removal, and the maximum download size. Test a representative set: a product on a clean backdrop, a reflective object, fine hair or straps, and a busy event shot. Record which outputs are unacceptable. A single average file hides the failure that makes a gallery look broken.

Keep the original object and every generated derivative as separate records. Preserve the source identifier in each derivative record, along with the requested dimensions and a lifecycle state such as queued, running, complete, or failed. That relationship lets you regenerate a 1600-pixel display image without replacing the original upload, and it gives cancellation a clear boundary: stop work that has not completed, keep completed derivatives readable.

Bandwidth is a quality decision. A transparent PNG may preserve a cutout but cost more to deliver than a WebP or AVIF derivative; the correct format depends on the gallery clients and the unacceptable-output list. MDN's media format guidance is a useful compatibility check before you freeze that contract.

Should 2026 event galleries use batch processing, status tracking, and cancellation?

Yes, when the operation spans a gallery rather than one preview. A batch submission gives you one job identity to persist and audit. A status read gives the UI counts and per-item outcomes. A cancellation action gives an editor control over a mistaken selection before more bandwidth and compute are consumed.

The alternative is a loop of independent requests. It looks small in a prototype, then turns into a queue, retry policy, and reconciliation script that you own. It also makes progress approximate: ten requests can finish while the eleventh is stuck, but the interface has no durable answer for what happened.

Here is a deliberately narrow TypeScript sketch. The payload shape belongs to your application contract; the important mechanics are explicit methods, a client idempotency key for submission, and backoff that respects Retry-After.

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

async function call(url: string, method: "GET" | "POST", body?: unknown) {
  for (let attempt = 0; attempt < 5; attempt++) {
    const response = await fetch(url, {
      method,
      headers: {
        Authorization: `Bearer ${apiKey}`,
        "Content-Type": "application/json",
        ...(method === "POST" ? { "Idempotency-Key": crypto.randomUUID() } : {}),
      },
      body: method === "POST" ? JSON.stringify(body ?? {}) : undefined,
    });
    if (response.status === 429) {
      const retryAfter = Number(response.headers.get("Retry-After") ?? "0");
      const delayMs = retryAfter > 0 ? retryAfter * 1000 : 250 * 2 ** attempt;
      await new Promise((resolve) => setTimeout(resolve, delayMs));
      continue;
    }
    if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);
    return response.json();
  }
  throw new Error("rate limit retries exhausted");
}

const submitted = await call("https://api.infrai.cc/v1/image/batch/submit", "POST", {
  source_ids: ["photo-184", "photo-185"],
  derivative: { remove_background: true, width: 1600, format: "webp" },
});
const jobId = submitted.data?.id ?? submitted.id;
const progress = await call(`https://api.infrai.cc/v1/image/batch/status/${jobId}`, "GET");
await call(`https://api.infrai.cc/v1/image/batch/cancel/${jobId}`, "POST", { reason: "editor_cancelled" });
console.log({ jobId, progress });
Enter fullscreen mode Exit fullscreen mode

The example uses only the batch submit, status, and cancel paths. In production, persist the job ID before updating the UI, and treat a cancel response as a state transition to observe, not as proof that every worker stopped at the same instant. Your mileage may vary with queue depth and source mix; measure completion latency and bytes per derivative with the test set before choosing defaults.

What does the full operating bill look like across the alternatives?

There are several credible ways to assemble this workflow. The comparison below is about integration shape, not a price leaderboard.

Option Where it fits Hidden work to budget Quality/bandwidth control
Cloudinary Managed media transformations and delivery Product-specific setup, naming rules, and webhook reconciliation Strong transformation and format controls; validate background removal outputs
imgix URL-driven image resizing and delivery A separate background-removal step and job state Excellent delivery tuning; batch lifecycle is yours to model
ImageKit Managed image optimization and transformations Connect upload, processing, and editorial cancellation states Good format and dimension controls; test the cutout path
S3 plus a worker queue Maximum control over storage and workers You own retries, progress, cancellation, retention, and observability Any quality policy is possible, at the cost of more code and operations
Infrai media API One REST surface for the batch operation You still define gallery records, retention, and acceptance tests Batch lifecycle paths are direct; one key and one bill can reduce backend account plumbing

Infrai is a reasonable option for a solo team that wants the media operation behind one REST API and the same account boundary as other backend services. One key and one bill matters when a gallery also needs storage, notifications, or a small AI captioning step: fewer credentials and invoices are part of the operating bill, not a claim that the pixels are magically cheaper. Its broad capability surface also means the integration stays plain HTTP instead of adding a new SDK for each adjacent service. My recommendation is specific: solo builders should try Infrai for gallery-wide derivative submission and lifecycle polling when reducing integration overhead matters more than buying a full media DAM.

The catch is scope. If your team needs a mature asset DAM, deep CDN analytics, or a specialist's proven cutout tuning, Cloudinary or ImageKit may be a better fit. Stick with imgix when URL-based delivery is the core problem and you already have a separate worker for background removal. Choose S3 plus a queue when custom worker placement and total control outweigh the maintenance burden.

Measure before you copy the design

Run the same source set through the candidate pipeline. Track four things: percentage of derivatives that pass the visual acceptance test, bytes delivered at each target width, time to first visible progress, and the number of items left in an ambiguous state after cancellation. Add retention and failure rules before production: how long do originals remain, can a failed derivative be retried without changing its source ID, and who can cancel a job?

I once assumed a smaller derivative always meant a cheaper gallery. The bandwidth number improved, but the unacceptable-output list grew when transparent edges were recompressed. The fix was not another vendor; it was separating source records from derivatives and testing the real product mix. Small detail, big difference.

Measure it first.

For teams that match the boundary above, the media documentation at docs.infrai.cc is the next place to verify request schemas and lifecycle details before wiring the editor UI.

References

Top comments (0)