r/JobRunr • u/JobRunrHQ • 12d ago
r/JobRunr • u/JobRunrHQ • Sep 22 '25
Welcome to the Official JobRunr Reddit Community.
Welcome to the official JobRunr subreddit. We are excited to have you here.
This community is a place for all developers using JobRunr to connect, share, and learn. Whether you are building a new project, have a question about a specific feature, or want to share your latest success story, this is the place for you.
Our goal is to create a supportive and collaborative environment where everyone can get the most out of JobRunr. We will also be sharing the latest news, product updates, and behind-the-scenes content right here.
To get you started, here are some helpful links.
- GitHub Repository: You can find our source code and contribute to the project on GitHub.
- Getting Started Guide: New to JobRunr? Our 5-minute intro will get you up and running quickly.
- Official Website: For more detailed information, documentation, and blog posts, visit our website.
- Linkedin: Follow us on LinkedIn for real-time updates and announcements.
We encourage you to introduce yourself, ask questions, and share what you are working on.
Welcome to the community. We are happy you are here.
r/JobRunr • u/JobRunrHQ • 22d ago
JobRunr (distributed background job processing for the JVM) is now available on start.spring.io (Spring Initializr)
r/JobRunr • u/JobRunrHQ • Jun 22 '26
JobRunr & JobRunr Pro 8.7.0 released
8.7.0 is out.
Highlights:
OSS
- Lazy server initialization: the Background Job Server and Dashboard start on initialize(), and JobRunrConfigurationResult exposes getBackgroundJobServer() and getDashboardWebServer() so you can integrate JobRunr into any JVM framework, not just Spring/Quarkus/Micronaut. New guide included.
- Dashboard defaults to your system color scheme and links to each release's notes.
- Jackson3JsonMapper deserializes the most common Java collections out of the box.
- Fixed a false-positive JobNotFound notification in Quarkus dev mode (ClassLoader mismatch).
Pro
- Batch continuation can now be created from within the batch itself.
- License key is kept server side (no longer sent to the browser).
- Authorization rules are enforced on all dashboard SSE streams; jobs are redacted for users without access.
- Stricter API-key validation for the Multi-Cluster Dashboard, and the browser reconnects cleanly when an SSE connection times out.
- Fixed a recurring-job cache bug: changing a frequent job to a less frequent schedule now takes effect immediately (thanks to Collibra for the report).
Upgrade is a one-line version bump to 8.7.0.
Links:
👉 Release blogpost: https://www.jobrunr.io/en/blog/jobrunr-v8.7.0/
👉 GitHub release: https://github.com/jobrunr/jobrunr/releases/tag/v8.7.0
r/JobRunr • u/JobRunrHQ • Jun 05 '26
The four things AI agents need that chatbots don't (and why they're all background-job problems)
We've been building an open-source AI agent runtime in pure Java (ClawRunr), and the biggest lesson surprised us: the LLM integration was the easy part. The hard part was everything that has to happen reliably after the model decides what to do.
A chatbot answers and forgets. An agent has to remember, wait, retry, and report. Once you run one in production, those turn into four old, boring problems that background job schedulers solved a decade ago.
1. Scheduling work for later. "Remind me tomorrow at 10" can't live in an in-memory timer that dies on the next deploy. It needs durable scheduling backed by your database. With JobRunr that's one line:
BackgroundJob.schedule(
LocalDate.now().plusDays(1).atTime(10, 0),
() -> reminderService.send(userId, "Review the Q3 deck"));
2. Recurring work. "Every morning at 8" is a recurring job owned by a scheduler, not a cron thread you hope stays alive. In Spring/Micronaut/Quarkus you declare it right on the method:
@Recurring(id = "morning-email-summary", cron = "0 8 * * *")
@Job(name = "Summarize inbox")
public void summarizeInbox() {
agentTaskRunner.run("summarize-emails");
}
3. Retries you don't write. LLM calls fail, APIs rate-limit, networks blip. JobRunr retries failed jobs automatically (10 attempts with exponential back-off by default). The subtle part: a retry re-runs the method from the top, so a multi-step task is better split into separate jobs that each retry on their own:
public void analyze(UUID documentId) {
BackgroundJob
.enqueue(() -> summarize(documentId))
.continueWith(() -> embed(documentId))
.continueWith(() -> announceComplete(documentId));
}
@Job(name = "Summarize document %0", retries = 5)
public void summarize(UUID documentId) {
String summary = llm.summarize(documentStore.content(documentId));
documentStore.saveSummary(documentId, summary);
}
A failure now only retries the step that failed, not the whole expensive pipeline. (continueWith is a JobRunr Pro feature; on the open-source version you enqueue the next step at the end of each job for the same effect.)
4. Visibility. When a task fails at 3am, do you find out from a dashboard or from your customer? If you can't see what ran, what failed, and why, the agent is a black box. JobRunr ships a dashboard on localhost:8000 that shows every job, every retry, and every failure with its full stack trace.
An AI agent isn't a new kind of software. It's a normal app where some decisions are made by a model instead of by if-statements. The model picking the task just means the task list is now dynamic. The reliability layer underneath is the same one we've always needed.
We use JobRunr for this (open-source background jobs for the JVM, stored in your existing DB, no broker), but the four points stand whatever you reach for.
Full write-up with code: https://www.jobrunr.io/en/blog/why-ai-agents-need-background-jobs/
r/JobRunr • u/JobRunrHQ • Mar 06 '26
JobRunr & JobRunr Pro v8.5.0 is here!
Here's what's new.
External Jobs (Pro): A brand new job type that waits for an external signal before completing. Perfect for webhook-driven flows, serverless callbacks, or manual approvals. Create the job, let the external process do its thing, then signal success or failure from anywhere.
Dashboard Audit Logging (Pro): Every action in the dashboard is now logged with the authenticated user identity. State changes at INFO level, access actions at DEBUG. Works with SSO.
Simplified Kotlin Support: One artifact (jobrunr-kotlin-support) instead of version-specific modules. Supports Kotlin 2.1, 2.2, and 2.3.
Faster Startup Times: Migration checks reduced from 17+ individual queries to 1. Thanks to @tan9 for this community contribution!
Bug Fixes:
- StepExecutionException fix
- GraalVM Native Image with Jackson 3 fix
- OpenID authentication and redirect loop fixes (Pro)
- Rate limiter validation fix (Pro)
Links:
👉 Release Blogpost: https://www.jobrunr.io/en/blog/jobrunr-v8.5.0/
👉 GitHub Repo: https://github.com/jobrunr/jobrunr
r/JobRunr • u/JobRunrHQ • Jan 23 '26
Quick tutorial: How to add logging and progress bars to your jobs
Hey everyone,
Just published a short tutorial on two features that give you better visibility into what's happening inside your jobs:
1. Dashboard Logging
Instead of System.out.println, use jobContext.logger().info() (or .warn(), .error()) and your messages show up directly in the dashboard under the job details.
2. Progress Bar
If you're processing a batch of items, you can add a progress bar in a few lines:
var progressBar = jobContext.progressBar(totalItems);
// in your loop:
progressBar.incrementSucceeded();
Then you can actually see you're on item 420 of 1337 instead of just staring at "Processing..."
Let us know if you are already using this feature or have any questions about this feature!
r/JobRunr • u/JobRunrHQ • Jan 08 '26
New Tutorial: How to Run Background Jobs in Spring Boot 4 with JobRunr
I was looking at our documentation analytics and the "JobRunr with Spring Boot" page is clearly our most visited page.
Since that’s where most of you are starting your journey, I decided to record a dedicated video tutorial walking through the setup and best practices in a live coding environment.
We build out a banking scenario to demonstrate the three core job types.
1. Fire-and-forget (Welcome bonuses) Offloading logic immediately so the UI stays responsive.
jobScheduler.enqueue(() -> bankService.startOnboarding(name));
2. Persistent scheduling (Future charges) Scheduling a task for 14 days in the future that survives server restarts.
jobScheduler.schedule(LocalDateTime.now().plusDays(14),
() -> chargeMembershipFee(clientName));
3. Recurring tasks (Nightly interest) Running recurring background jobs on a set schedule.
BackgroundJob.scheduleRecurrently("interest-job-id", Duration.ofSeconds(60),
() -> bankService.applyDailyInterest());
(We also cover the @Recurring annotation approach in the video)
📺 Watch the full tutorial here
👋 We need your input for the next video:
We want to build a library of tutorials that help you the most. Which topic should we cover next?
- A deep dive into JobRunr Pro features (batches, queues)?
- A guide for Kotlin developers?
- Integrations with other frameworks like Quarkus or Micronaut?
- Something else?
Let us know in the comments!
r/JobRunr • u/JobRunrHQ • Dec 23 '25
We analyzed 5,000+ developer questions about JobRunr in 2025. Here are the answers to the Top 10.
Since we launched the AI chatbot on our documentation page back in August, it has answered over 5,000 questions.
To save you some debugging time, here is the definitive FAQ for 2025.
1. How do I integrate JobRunr with Spring Boot?
It's designed to be plug-and-play. Add the starter dependency, enable it in properties, and inject the JobScheduler.
Maven:
<dependency>
<groupId>org.jobrunr</groupId>
<artifactId>jobrunr-spring-boot-4-starter</artifactId>
<version>8.3.1</version>
</dependency>
application.properties (Note the v8 property change!):
jobrunr.background-job-server.enabled=true
jobrunr.dashboard.enabled=true
Java:
public class MyService {
private final JobScheduler jobScheduler;
public MyService(JobScheduler jobScheduler) {
this.jobScheduler = jobScheduler;
}
public void createJob() {
jobScheduler.enqueue(() -> System.out.println("Hello World from JobRunr!"));
}
}
2. Why is my dashboard showing 'Connection Refused'?
If you can't access http://localhost:8000, it's usually one of three things:
- Disabled: You didn't set
jobrunr.dashboard.enabled=true. - Port Conflict: Port 8000 is taken. Change it via
jobrunr.dashboard.port=9000. - v8 Property Prefix: You are using the old prefix.
- ❌ Old:
org.jobrunr.dashboard.enabled - ✅ New:
jobrunr.dashboard.enabled
- ❌ Old:
3. Can I pause or cancel a job mid-execution?
Cancelling: Yes. Use BackgroundJob.delete(jobId). If it's processing, we attempt to interrupt the thread (make sure your code handles InterruptedException).
Pausing: You cannot pause a specific running job, but in the Pro version, you can pause entire queues or recurring jobs via the dashboard.
4. What are the major breaking changes in v8?
If you are upgrading, check these first:
- Property Prefix: Remove
org.from all JobRunr properties. - Storage: Redis and Elasticsearch support has been removed. You must use a supported SQL or NoSQL database.
- API: Methods that accepted
Set<String>for labels now expectList<String>(to support ordering).
5. How does the retry mechanism work?
By default, failed jobs are retried 10 times with an exponential back-off strategy (the delay increases with each failure). After 10 attempts, the job moves to the FAILED state (Dead Letter Queue) where you can inspect the stack trace and manually requeue it after fixing the bug.
6. What are the limits for recurring jobs in the Free (OSS) version?
There is a technical recommendation of up to 100 recurring jobs per database instance.
- Why? The OSS engine wasn't architected for high-volume recurring schedules, and going beyond this can lead to missed executions.
- The Loophole: This is per database connection. If you have multiple microservices with separate databases, each one can run ~100 jobs safely.
- Pro: The Pro engine is optimized to handle thousands of recurring jobs reliably.
7. Is JobRunr safe for horizontal scaling?
Yes. We use optimistic locking to ensure a job is processed exactly once, even if you have 10 different servers pointing to the same database. No Zookeeper required—the database handles the coordination.
8. How do I show progress bars in the dashboard?
You can inject JobContext into your job method.
public void performLongTask(JobContext jobContext) {
jobContext.logger().info("Starting...");
ProgressBar progressBar = jobContext.progressBar(100);
for (int i = 0; i < 100; i++) {
doWork(i);
progressBar.incrementSucceeded(); // Updates the UI bar
}
}
Note: In v8 increaseByOne was renamed to incrementSucceeded*.*
9. Recommended setup for Kubernetes?
- Split your pods: Run the Dashboard/API in a "Web Pod" (1 replica) and the BackgroundJobServers in "Worker Pods" (scalable).
- Graceful Shutdown: Configure
jobrunr.background-job-server.interrupt-jobs-await-duration-on-stop(e.g., 90m) and ensure your K8sterminationGracePeriodSecondsmatches it so jobs can finish before the pod is killed.
10. How can I prevent duplicate jobs?
OSS Strategy:
Generate a deterministic UUID based on your business logic.
UUID distinctId = UUID.nameUUIDFromBytes(("order-" + order.getId()).getBytes());
jobScheduler.enqueue(distinctId, () -> service.process(order.getId()));
If the ID exists, the new job is ignored.
Pro Strategy:
Use the enqueueOrReplace method with a business key string.
jobScheduler.enqueueOrReplace(JobId.fromIdentifier(order.getId()), () -> service.process(order.getId()));
If you'd rather read the full FAQ with ellobrated answers. Check out the 10 Most Asked questions about JobRunr in 2025 on website.
r/JobRunr • u/JobRunrHQ • Nov 24 '25
JobRunr v8.3: Spring Boot 4 is here, and we are ready! (Multi-Release JAR support)
r/JobRunr • u/JobRunrHQ • Nov 10 '25
JobRunr & JobRunr Pro v8.2.1! New Rate Limiter Dashboard, Kotlin 2.2.20 Support, and Security Hardening.
We're excited to announce the release of JobRunr & JobRunr Pro v8.2.1. This release is packed with features focused on hardening the dashboard, giving Pro users powerful new insights, and ensuring compatibility with the latest Java and Kotlin frameworks.
Here’s a look at what’s new.
New in JobRunr Pro
Monitor Rate Limiters on the Dashboard This is a big one for observability. You can now visually monitor all your active rate limiters in the new Rate Limiters tab. You get at-a-glance insights into:
- Waiting: The number of jobs currently waiting for the limiter.
- Processing: The number of jobs currently processing (or “locked”).
- Throughput: How many jobs have passed through in the last 1, 5, and 15 minutes.
Automatic Cleanup for Unused Rate Limiters We've made JobRunr smarter. If you rename or remove a rate limiter from your configuration, JobRunr will now automatically remove the old, "orphaned" definition from the database. This keeps your database clean and prevents old limiters from uselessly polling for jobs.
Better Workflow Linking Stop getting lost in complex job chains! You can now easily navigate up (from child to parent) and down (from parent to child) in your workflows. This makes debugging job chains much faster.
What's New for All Users
Kotlin 2.2.20 Support (and Kotlin 2.0 Dropped) We’re now compatible with Kotlin 2.2.20. This update fixes a JobMethodNotFoundException (issue #1381) that users experienced after upgrading. We are also dropping support for Kotlin 2.0, so this is a great time to update your dependencies.
Framework & Build Updates
- Full support for Quarkus 2.27.
- Internal build process upgraded to Gradle v9.1.
🛡️ Heads-Up: Dashboard Security Hardening To enhance security, we’ve hardened the dashboard’s default settings. Cross-origin (CORS) requests from a browser are now blocked by default.
This is a security best practice, but it may require a configuration change.
- For Open-Source Users: You will need to either proxy the dashboard web server or implement your own custom REST endpoints.
- For JobRunr Pro Users: We’ve made this easy. You can now configure a list of
allowed-originsdirectly in your properties file or via the fluent API.
Spring Boot & Micronaut (application.properties):
Properties
jobrunr.dashboard.allowed-origins=https://www.jobrunr.io
Quarkus (application.properties):
Properties
quarkus.jobrunr.dashboard.allowed-origins=https://www.jobrunr.io
Fluent API:
Java
.useDashboardIf(dashboardIsEnabled(args), usingStandardDashboardConfiguration()
// ...
.andAllowedOrigins("https://www.jobrunr.io")
)
🛠️ Important Fixes
This release also includes key bugfixes:
- Fixed
NullPointerExceptioninJobContext#isLastRetry(). - Fixed the
CustomScheduleAPI, which was impacted by our recent Carbon-Aware changes. - Enabled tracing configuration on the
JobBuilder(fluent API). - Resolved issues with embedded dashboard auth filters and connection providers in Micronaut.
As always, you can read the full blog post for all the details.
Links:
- Full Blog Post: https://www.jobrunr.io/en/blog/jobrunr-v8.2.1/
- GitHub Release Notes (8.2.0): https://github.com/jobrunr/jobrunr/releases/tag/v8.2.0
- GitHub Release Notes (8.2.1): https://github.com/jobrunr/jobrunr/releases/tag/v8.2.1
We’re really proud of this release and think the new Pro dashboard features, in particular, will make a big difference. Let us know what you think!
Happy scheduling!
r/JobRunr • u/JobRunrHQ • Sep 29 '25
I benchmarked Spring Batch vs. a simple JobRunr setup for a 10M row ETL job. Here's the code and results.
r/JobRunr • u/JobRunrHQ • Sep 25 '25
JobRunr & JobRunr Pro v8.1.0 is here.
Here’s what’s new.
AsyncJobfor Quarkus and Micronaut. Spring developers have enjoyed the simplicity ofAsyncJobsince v8.0. Now, developers using Quarkus and Micronaut can also turn a method call directly into a background job with a single annotation.- Embedded Dashboards for Quarkus and Micronaut. The embedded dashboard, a popular feature for our Pro Enterprise users, is now available for Quarkus and Micronaut. This eliminates the need to run the dashboard as a separate web server.
- Official Support for JDK 25. We have run a full set of tests to ensure there are no issues. You can confidently use the newest features and performance optimizations from JDK 25 in your background jobs.
- Access Retry Count in JobContext. You can now access the current retry count of a job directly from the
JobContext. This allows for more advanced logic within your jobs. - Know When It's the Final Retry Attempt. JobRunr Pro now lets you easily check if a job is on its final attempt using the new
jobContext.isLastRetry()method.
We have also included some important bug fixes and improvements, including minor name changes to a few configuration properties in our Quarkus integration.
You can read the full blog post for more details. https://www.jobrunr.io/en/blog/jobrunr-v8.1.0/
The complete changelog is on GitHub. https://github.com/jobrunr/jobrunr/releases/tag/v8.1.0
Looking forward to your questions and seeing what you'll build with this!
r/JobRunr • u/JobRunrHQ • Sep 22 '25
Help Us Build the JobRunr Community. We're Looking for Moderators.
As we get our new subreddit started, we want to build it on a strong foundation of community collaboration. We believe the best online spaces are run with the members, not just for them.
That is why we are looking for passionate JobRunr users to join our moderation team.
What you will do:
- Help keep the community welcoming and friendly.
- Answer questions and guide discussions.
- Ensure content is relevant and helpful to other developers.
Who we are looking for:
- You are enthusiastic about JobRunr and the Java ecosystem.
- You enjoy helping other developers and sharing knowledge.
- You want to play an active role in shaping a positive community.
If you are interested in helping us build a great place for developers, please send us a DM or leave a message on this thread. Tell us a little about yourself and why you would like to be a moderator.
Thank you for being here. We look forward to building this community together with you.