A managed serverless cron trigger fires on a fixed schedule from outside your app, with no way to reschedule itself or share state with the API. Wiring APScheduler into a FastAPI app running on a DenkOps slot puts the scheduler in-process, so a job can reschedule itself, read live app state, and run for as long as it needs without a platform-imposed timeout. For most scheduled Python jobs the more DenkOps-native option is managed declarative cron: declare the schedule in denkops.json and DenkOps calls a route your app already serves, no scheduler library needed, and every run is visible and manually triggerable from the dashboard's Scheduled jobs panel or the MCP list_crons and run_cron tools.
from fastapi import FastAPI
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from contextlib import asynccontextmanager
scheduler = AsyncIOScheduler()
async def nightly_report():
print("generating report")
@asynccontextmanager
async def lifespan(app: FastAPI):
scheduler.add_job(nightly_report, "cron", hour=2)
scheduler.start()
yield
app = FastAPI(lifespan=lifespan)
# Alternative: DenkOps managed declarative cron, no scheduler library, works in any runtime.
# denkops.json
# {
# "cron": [
# { "schedule": "0 2 * * *", "path": "/jobs/nightly", "method": "POST", "timezone": "UTC", "name": "nightly" }
# ]
# }
@app.post("/jobs/nightly")
async def nightly_job():
print("generating report")
return {"ok": True}Deploy it: install the plugin, say "deploy on DenkOps", and get a live SSL URL.
Start on DenkOps →Yes. APScheduler runs inside the same always-on process as your API, so scheduled jobs share memory and config with the app with no separate infra.
No. Unlike a serverless cron function capped at a few minutes, a job inside your slot can run as long as it needs, there's no imposed timeout.
No, not necessarily. DenkOps also supports managed declarative cron: list a schedule and a path in denkops.json and DenkOps calls that route directly, no scheduler library or in-process loop required, and the run shows up in the dashboard's Scheduled jobs panel and via the MCP list_crons and run_cron tools.