All jobs run via Hangfire with PostgreSQL storage. The Hangfire dashboard is atDocumentation Index
Fetch the complete documentation index at: https://docs.aspfox.com/llms.txt
Use this file to discover all available pages before exploring further.
/hangfire (requires is_admin JWT claim).
Job schedule reference
| Job | Cron schedule | Batch size | What it does |
|---|---|---|---|
trial-expiry | 0 9 * * * (daily 9:00 AM UTC) | 100 tenants/run | Sends 7-day and 1-day trial warning emails. Expires trials that have ended and downgrades tenants to Free. |
subscription-sync | 0 */2 * * * (every 2 hours) | All tenants with Stripe subscriptions | Fetches current subscription state from Stripe and reconciles with local database. Recovers from missed webhooks. |
token-cleanup | 0 3 * * * (daily 3:00 AM UTC) | All expired tokens | Deletes expired refresh tokens, password reset tokens, email verification tokens, and magic link tokens. |
invitation-cleanup | 0 4 * * 0 (weekly Sunday 4:00 AM UTC) | All expired invitations | Removes invitations that expired more than 30 days ago. Keeps recently expired ones visible for resend. |
Retry behavior
All jobs use the same retry policy: 3 attempts with exponential backoff.| Attempt | Delay after failure |
|---|---|
| 1st retry | 60 seconds |
| 2nd retry | 300 seconds (5 minutes) |
| 3rd retry | 900 seconds (15 minutes) |
What to do when a job fails repeatedly
- Go to
/hangfire→ Failed Jobs - Click on the failed job to see the full exception and stack trace
- Fix the root cause (usually a database connectivity issue, Stripe API error, or configuration problem)
- Click Requeue to retry the job immediately
- Monitor the job’s next scheduled run to confirm it succeeds
token-cleanupfails → usually a PostgreSQL connectivity issuesubscription-syncfails → usually a Stripe API rate limit or network issue; retries automaticallytrial-expiryfails → usually an email delivery issue; check Resend dashboard
Triggering a job manually
From the Hangfire dashboard:- Recurring Jobs tab
- Find the job by name
- Click Trigger now
Disabling a job
To disable a job without deleting it:Viewing job history
Hangfire stores the execution history of every job run. From the dashboard:- Succeeded — completed runs with duration and timestamp
- Failed — failed runs with exception details
- Recurring Jobs — next scheduled run, last execution status
HangfireConfiguration.cs.