Skip to main content

Python cron jobs without the server.

A crontab on a box nobody patches, running a script that logs to a file nobody reads. On qbash the same script runs on your schedule, with a log for every run.

The standard setup.

A crontab entry on a Linux server, calling a Python script at an interval. Simple to start, expensive to maintain.

crontab
# crontab -e
0 8 * * 1 cd /home/deploy && python3 report.py >> /var/log/report.log 2>&1
  • Works on any Linux server with Python installed.
  • No queue, broker, or platform to install.
  • Familiar to anyone who has administered a Unix system.

Where it breaks.

The server is the single point of failure, and everything around it drifts.

  • The server has to stay up. A reboot, a disk failure, or a missed patch kills every job on the host.
  • No retry. A failed run is a missed run. You find out when someone notices the data is stale.
  • Logs go to stdout or a file. Finding what went wrong means SSH, grep, and hope.
  • The crontab and the script drift apart. Someone edits one without updating the other.
  • Dependencies rot. The Python version, the pip packages, and the OS underneath all age at different rates.
  • No rollback. A broken change means restoring from backup or rewriting under pressure.

qbash Tasks.

A Task is an AI automation written in Python, hosted on a managed runtime. A developer writes the script; anyone runs it from a form. Integrations, model calls, version control, and logging are built in.

Model and provider agnostic.

  • Anthropic
  • OpenAI
  • Gemini
  • xAI
  • OpenRouter
  • Amazon
  • Perplexity
  • MoonshotAI
  • Meta
  • Qwen

A scheduled task on a managed runtime.

Write the script, set the schedule, and the platform handles the server, the runtime, and the logs.

  • Set a cron expression and the task runs on schedule, with no server or process manager to maintain.
  • Every run is logged with inputs, output, errors, and duration.
  • Every save is a revision with a line-level diff and one-click rollback.
  • Retry with checkpoints. A failure picks up where it left off.
  • The runtime, the interpreter, and the Python environment are managed by the platform.
report.py
rows = qbash.integrations.postgres.execute_query(
    query="SELECT department, sum(amount) FROM expenses "
    "WHERE date >= current_date - interval '7 days' "
    "GROUP BY department"
)["result"]

report = qbash.ai.run_prompt(
    slug="weekly-expense-summary",
    variables={"rows": rows},
)

qbash.integrations.slack.create_message(
    channel="#finance", text=report["summary"],
)

qbash.integrations.outlook.send_message(
    to_recipients="cfo@example.com",
    subject="Weekly expense summary",
    body=report["body"],
)

Runs without a host.

The server and the crontab are handled by the platform, and every run is logged with what happened.

Version history and rollback

Every save writes a revision with a line-level diff. The cron expression and the script live in the same place, so a change to either shows up in the same history. Any revision restores in one click.

Output goes where the work happens

Send results to Slack, email, Asana, or a database in one line. 45+ integrations with credentials brokered server-side. The cron job output goes where the team already works, not to a log file.

alert.py
issues = qbash.integrations.postgres.execute_query(
    query="SELECT * FROM checks WHERE status = 'failing'"
)["result"]

if issues:
    qbash.integrations.slack.create_message(
        channel="#alerts",
        text=f"Found {len(issues)} failing checks",
    )

    for issue in issues:
        qbash.integrations.asana.create_task(
            name=issue["name"], project_gid="1200000000000001",
            notes=issue["details"],
        )

Parallel processing

Fan out over hundreds of items with concurrency and rate limiting as arguments. Checkpoints skip the items that already finished, so a retry does not repeat work.

batch.py
results = qbash.parallel(
    check_endpoint, endpoints,
    concurrency=10, max_per_minute=60,
    checkpoint="health-check", retry=2,
)

failures = [r for r in results.results if not r["healthy"]]

How it compares with other schedulers.

Each option starts your code on a timer. They differ in where the code runs and how much you set up around it.

Web cron servicesAWS EventBridge and LambdaGoogle Cloud Schedulerqbash
What runs on the scheduleAn HTTP call to a URL you hostA Lambda functionAn HTTP, Pub/Sub or App Engine target you deployThe Python Task itself
Where the code runsYour own server or appLambdaCloud Run, Cloud Functions or a VMqbash
SetupExpose an endpoint, then add its URLAn IAM role, a function package and a ruleA service account, a target service and a jobWrite the Task, then add a schedule
Longest runWhatever your server allows15 minutesWhatever your target allows15 minutes on Free, 12 hours on paid plans
Run historyResponse codesCloudWatch LogsCloud LoggingLogs and output for every run
What runs on the schedule
Web cron servicesAn HTTP call to a URL you host
AWS EventBridge and LambdaA Lambda function
Google Cloud SchedulerAn HTTP, Pub/Sub or App Engine target you deploy
qbashThe Python Task itself
Where the code runs
Web cron servicesYour own server or app
AWS EventBridge and LambdaLambda
Google Cloud SchedulerCloud Run, Cloud Functions or a VM
qbashqbash
Setup
Web cron servicesExpose an endpoint, then add its URL
AWS EventBridge and LambdaAn IAM role, a function package and a rule
Google Cloud SchedulerA service account, a target service and a job
qbashWrite the Task, then add a schedule
Longest run
Web cron servicesWhatever your server allows
AWS EventBridge and Lambda15 minutes
Google Cloud SchedulerWhatever your target allows
qbash15 minutes on Free, 12 hours on paid plans
Run history
Web cron servicesResponse codes
AWS EventBridge and LambdaCloudWatch Logs
Google Cloud SchedulerCloud Logging
qbashLogs and output for every run
  • A web cron service fits a job that already sits behind a URL, and EventBridge or Cloud Scheduler fit teams already deploying to AWS or Google Cloud.
  • For a Python job with no deployment of its own, the Task holds both the code and the schedule.

When a Python job outgrows the Lambda 15-minute timeout.

The Lambda timeout defaults to 3 seconds and goes up to 900 seconds in Configuration > General > Timeout. Past 15 minutes, the AWS path is Step Functions, which chains invocations with a state machine defined in JSON plus IAM roles. ECS removes the timeout but adds containerization. A task runs the same Python for up to 12 hours.

  • When a Lambda times out, in-flight work is lost and a retry starts from scratch. qbash.parallel records which items finished, so a run that fails at item 4,000 of 10,000 resumes at 4,001.
  • Each task has an API endpoint. Your Lambda calls it over HTTP and returns immediately while the task runs in the background.
  • The default expected runtime is 15 minutes or less, and a run that goes past it is stopped and recorded as timed out. Pick the 12-hour preset in the task settings for long jobs.
  • Lambda stays the better fit for short, event-driven functions such as API handlers, webhook processors and lightweight transformations.
process.py
items = qbash.integrations.postgres.execute_query(
    query="SELECT * FROM items WHERE processed = false"
)["result"]

results = qbash.parallel(
    process_item, items,
    concurrency=10, max_per_minute=120,
    checkpoint="batch-process", retry=3,
)

qbash.integrations.slack.create_message(
    channel="#data", text=f"Processed {results.completed} items",
)

Questions

Is there a free plan?

Yes. The Free plan includes scheduled runs, 3 Tasks and 100 executions a month, and each run can last up to 15 minutes. Paid plans start at $37 a month and allow runs of up to 12 hours.

How is this different from a web cron service such as EasyCron or cron-job.org?

A web cron service calls a URL on a schedule, so the code still runs on a server you host. On qbash the scheduled Task is the code.

Can I use this instead of EventBridge or Cloud Scheduler?

Yes, for Python jobs. Set the cron expression on the Task. Jobs that must run inside your own AWS or Google Cloud network belong on those services.

Can I set any cron schedule?

Yes. Standard cron expressions. The task runs on the managed runtime at the interval you set.

What if a scheduled run fails?

The run is logged with the error. You can configure retry with checkpoints so a failed run resumes where it left off rather than starting over.

How is this different from GitHub Actions on a cron?

GitHub Actions runs a workflow in a container on a schedule. A task is comparable in that it is scheduled, but the runtime is purpose-built for long-running Python with integrations, model calls, and persistent state. Actions has a 6-hour timeout, no built-in retry from a checkpoint, and no run-level logging beyond workflow output.

Can a task run longer than a few minutes?

Up to 12 hours. Long-running data processing, backfills, and batch jobs are expected use cases.

Can AWS Lambda run longer than 15 minutes?

A single invocation cannot. 900 seconds is the hard ceiling. AWS Lambda durable functions, launched in December 2025 for Python and Node.js, checkpoint each completed step of a multi-step function and skip those steps when it replays, so one workflow can span many invocations and suspend for up to a year. You write those steps with the AWS durable execution SDK.

Why not use Step Functions?

Step Functions works. It adds state machine definitions, IAM policies, execution roles, and a separate deployment pipeline. If you are already in the AWS ecosystem and need complex branching logic, Step Functions fits. If you need to run a Python script longer than 15 minutes, a task does that with one file.

What about APScheduler or the schedule library?

Those libraries run inside a long-lived Python process you host yourself. The server and the process manager are still yours to maintain. A qbash task removes both.

Competitor details reviewed . Vendors change plans and features without notice, so check theirs before deciding.

Ship your first task.

Put a script on a cron and it runs unattended, with every execution logged and every change versioned.