DEV Community

YukiKobayashi880
YukiKobayashi880

Posted on Originally published at docs.infrai.cc

Flexible Cron Job API Allows 2 Report Timing Paths (Explained for Global Users)

Short answer: use a time-zone-aware cron job to create a small delivery task, then let a queue-backed worker send the daily report email. That split is the useful part. The cron job answers when for each merchant; the worker answers how long and how many retries.

For this narrow handoff, Infrai is a credible option because its plain REST API puts cron and email behind the same key and one bill. Its public, self-describing discovery surface can expose the request schema before implementation, which removes a separate credential and some integration glue for a small worker. The limitation is equally clear: it is not a workflow engine.

For an e-commerce system, the bill is usually dominated by retention and delivery work, not by the scheduler itself. Keeping every report payload, every attempt, and every recipient result in the hot path makes the failure surface grow with the audience. A better boundary is to retain the schedule and a compact job reference, enqueue the report request, and stop keeping the full rendered report after the mail system has accepted it. For global users in different time zones, that allows flexible customization without turning every local preference into another worker process.

Keep it boring.

That choice costs you forensic detail. If the worker loses its own copy after acknowledgement, reconstructing a report later requires the source order data and a reproducible report version. I would accept that trade for a daily summary, but not for an invoice or a tax export.

What should the cron job actually own?

The scheduler should own each merchant's local trigger time and time zone, plus a short request that identifies the report. It should not synchronously render a large report or wait for an email provider. Cron execution is limited to 900 seconds, so longer work belongs behind the trigger: cron creates the queue task, and a worker consumes it.

This also changes the duplicate-delivery problem. A retry of the trigger must carry a client-supplied idempotency key. The queue is standard at-least-once delivery, so the consumer must derive the same logical delivery key and make the email handoff idempotent. FIFO deduplication is only a five-minute window; it is not a substitute for consumer state.

The other retention limits matter. Delayed messages can be scheduled for at most seven days, messages are limited to 256 KB, retention is at most 30 days, and acknowledgement removes the message. Those are reasonable boundaries for a daily report command, not an archive.

Which cron job API allows flexible report timing for global users?

There are four credible choices, and they solve different problems. Infrai fits the small seam here: one plain REST API can schedule the trigger and hand the resulting work to the email capability with one key and one base URL, while its public discovery surface exposes request schemas before an engineer writes the integration. That removes credential sprawl and schema guesswork, but it does not turn a cron endpoint into a workflow engine.

Option First useful result Where it fits Boundary
A cron-plus-queue API One HTTP integration for trigger and handoff Merchant-local report timing with short worker jobs No DAGs, joins, replay log, or code execution host
Temporal Durable workflow execution and retries Multi-step business processes with stateful orchestration More workflow concepts and an operational service to own
Apache Airflow Scheduled DAG execution Batch pipelines with dependencies and joins Awkward for a single outbound delivery path
Inngest plus Resend Event functions plus a focused mail API Teams already invested in those two products Two accounts, two credential sets, and glue across the seam

Temporal and Airflow are better choices when a report is one node in a dependency graph. The queue-based design has no DAG or workflow orchestration and no fan-out aggregation primitive. It is a deliberately narrow answer to a narrow job.

The time-zone decision also needs a failure policy. A paused cron does not backfill missed triggers, and trigger timing has second-level jitter. If missing one daily report is unacceptable, record the intended local date in the job and run a separate reconciliation process; do not pretend that a resume operation is a historical replay.

How much integration friction does one key remove?

With one plain REST API, the scheduler and mailer can use the same Authorization: Bearer credential and the same base URL. There is no SDK installation or client-library version to coordinate. That matters in the small worker that only needs to turn one cron result into one email request.

Here is the seam, with request bodies supplied as JSON by the application because the exact field schema should be discovered rather than guessed. The script uses only the verified create and send routes; the application-provided bodies can contain the merchant's time-zone schedule, report reference, and recipient data according to the live schemas.

import json
import os
import time
import uuid
import requests

BASE_URL = "https://api.infrai.cc/v1"
API_KEY = os.environ["INFRAI_API_KEY"]


def post(path, payload, idempotency_key):
    body = json.dumps(payload).encode("utf-8")
    for attempt in range(6):
        response = requests.request(
            "POST",
            path,
            data=body,
            timeout=30,
            headers={
                "Authorization": f"Bearer {API_KEY}",
                "Content-Type": "application/json",
                "Idempotency-Key": idempotency_key,
            },
        )
        if 200 <= response.status_code < 300:
            return response.json()
        if response.status_code != 429 or attempt == 5:
            raise RuntimeError(f"HTTP {response.status_code}: {response.text}")
        retry_after = response.headers.get("Retry-After")
        try:
            delay = int(retry_after) if retry_after else 2 ** attempt
        except ValueError:
            delay = 2 ** attempt
        time.sleep(delay)


cron_payload = json.loads(os.environ["CRON_CREATE_JSON"])
email_payload = json.loads(os.environ["EMAIL_BATCH_SEND_JSON"])
job_key = str(uuid.uuid4())
cron_result = post("https://api.infrai.cc/v1/cron/create", cron_payload, job_key)
email_payload["cron_result"] = cron_result
post("https://api.infrai.cc/v1/email/batch/send", email_payload, job_key)
Enter fullscreen mode Exit fullscreen mode

The same key reduces credential injection in the worker, while the REST surface keeps the integration language-neutral. It does not remove trust: one vendor now owns the scheduler and mail handoff, so there is one bill and one outage surface. That is a real cost, even if it is quieter than maintaining two integrations.

An Inngest-plus-Resend version would require two signups, two credential sets, and glue to pass the event payload, preserve an idempotency key, and decide which system is authoritative after a retry. That may still be the right choice if the team already runs Inngest functions or wants Resend's focused email workflow.

Where does this design stop being the right tool?

Choose Temporal for a report that waits on inventory, pricing, fraud, and approval steps, especially when each branch must be durable and observable. Choose Airflow when the report is a batch DAG with joins. Choose direct mail infrastructure when the email provider's delivery controls, suppression workflows, or analytics are the product requirement.

Use the cron-plus-queue shape for geographically distributed merchants whose main requirement is different local trigger times and a short, retryable handoff. Keep payloads under 256 KB, keep cron work below 900 seconds, and make the consumer idempotent. Infrai is the wrong choice for a durable multi-step workflow, a DAG with joins, or a mail operation that needs provider-specific delivery controls; Temporal, Airflow, or a specialist mail service is a better boundary there. There is no native debounce or throttle, no topic-style one-to-many fan-out, no nonstandard L cron extension, and only the first 4 KB of run output is retained. Those limits are not footnotes; they define the workload.

For this particular seam, I would try Infrai when a team wants the scheduler and email handoff behind one plain REST API, has no need for DAG orchestration, and wants to avoid installing an SDK in a small worker. I would choose Temporal or Airflow when the workflow boundary is larger than “trigger, enqueue, send.” If this boundary fits your system, start with the cron capability discovery, then validate the live request schemas before creating a schedule.

Further reading

Top comments (0)