How Apache Fineract scheduler jobs run your end-of-day processing
Your loans and savings accounts change overnight without anyone clicking anything. Two separate mechanisms do that work in Apache Fineract: scheduled jobs driven by Quartz, and the Close of Business (COB) Spring Batch job. Each has its own configuration, and each needs an owner before go-live. Knowing which background work runs, when it runs, and what it changes is the first control an operations lead should put in place.
The scheduled jobs are the smaller, more frequent tasks that Fineract runs on a timer. You can review and enable or disable them through the global configuration in Fineract, so the operations team should record which jobs are on in each environment and why. Disabling a job is a change to platform behavior, so it belongs under the same change control as other global settings. Confirm the current list of jobs and their default states against the platform documentation for the release you deploy, because the set can change between versions.
The COB job is different in scale. The Fineract README warns that it can run for several hours on deployments with millions of accounts, and it supports remote partitioning across worker nodes coordinated through ActiveMQ or Kafka. Plan a fixed business-day window for COB, agree who is notified when it runs long, and test its duration against a copy of your own account volumes rather than assuming the sample size is representative. Ask your implementation partner to document how COB steps are ordered through the API and where run history can be checked, so that a stalled night can be diagnosed without guesswork.
Which instance should run scheduled work
The Fineract documentation describes a batch instance type for background and long-running work, and recommends one batch instance per deployment. Scheduled Quartz jobs and the Close of Business (COB) Spring Batch job belong here. COB can run for several hours on deployments with millions of accounts, so the batch instance and its database connections need to tolerate a long-running process.
- Scheduled jobs: Jobs that post interest, apply charges or run other periodic processing are assigned to this role, so confirm which ones run on batch in your version.
- Single instance: Two batch instances can trigger the same job against the same accounts. Confirm how the platform prevents duplicate runs before you scale this role.
- COB duration: Plan monitoring and timeouts for a process that may run for hours, not minutes.
- Remote partitioning: COB can distribute work to worker nodes coordinated through ActiveMQ or Kafka. Worker nodes are a separate design decision, so confirm their configuration before adding them.
- Maintenance windows: Restarting or redeploying the batch instance during COB can leave locks behind, so agree on a window with operations.
Check that exactly one running pod has the batch instance type enabled and that no autoscaler or second Deployment copies that setting.
The write instance type handles the API requests that change state, such as creating clients, posting transactions and approving loans. The documentation also states that Liquibase database migrations run only on write instances. On Kubernetes, the migrations can run as a separate job with the liquibase-only Spring profile, which keeps schema changes out of the normal startup path.
- Transaction traffic: User-initiated writes belong on this role, and they compete with any heavy background work on the same pods.
- Migration ordering: During an upgrade, the Liquibase step must complete before new write pods accept traffic. Confirm the ordering in your release notes.
- Scheduled work leakage: If scheduled jobs are enabled on write pods, they can run alongside user transactions and multiply with each replica.
- Write scaling: The documentation recommends one write instance for the standard pattern. Confirm with the project documentation before running more than one.
- Connection use: Write pods hold connections to the primary database, so connection limits should be set with the write role in mind.
Before go-live, check that the write Deployment does not enable batch behavior and that migration runs once per release, not once per pod.
Read instances serve query traffic that does not change data. The documentation recommends multiple read instances on database read replicas for high load. This role suits reporting, lookups, statement views and dashboards that would otherwise compete with posting traffic on the primary database.
- Query offload: Heavy read patterns move to replicas, which protects the primary during business hours and COB.
- Replication lag: Replicas can trail the primary. Define the acceptable lag for balance and statement views with the business owners before go-live.
- No scheduled work: Jobs should not run on read pods. Multiple read replicas that each fire a scheduled job would repeat the same work many times.
- Horizontal scale: Add read replicas and read instances together, and confirm each new pod carries the read instance type.
- Failover behavior: Confirm how read pods behave when a replica is promoted or removed, and whether they reconnect automatically.
Test that a read pod runs no job entries in its logs or job history after deployment, and that its database connection points at a replica.
The instance type environment variables decide which pod runs scheduled work, and the exact variable names and accepted values depend on the Fineract version in use. Confirm these in the platform documentation for your release before writing deployment manifests, because a setting copied from an older example can assign the wrong role. The check should happen in the staging environment and again after every upgrade.
- Confirm the variable names: Read the instance type section of the documentation for your exact version and record the variables in your configuration standard.
- Count the batch pods: Expect one running pod with the batch role. Zero means no scheduled jobs run, and two or more means duplicate runs are possible.
- Check the job history: After a deployment, review the job run history to confirm each job ran once at its scheduled time and on the expected pod.
- Review replica counts: Autoscalers and Helm values can silently change replica counts, so alert on changes to the batch Deployment.
- Test failover: Restart the batch pod during a non-production COB and confirm the job's recovery behavior with your operations team.
Record the results in your change record, so auditors and operators can see which pod held each role on any given date.
Job and COB settings to review and when each fits
This table lists the control points that change how scheduled jobs and Close of Business run in a Fineract deployment. Read each row as a decision: what the setting changes, when it fits your operating model, and what to confirm in the documentation for the release you run.
| Control point | What it changes | When it fits and what to confirm |
|---|---|---|
| Enabling or disabling individual scheduled jobs | Turns specific Quartz-scheduled background jobs on or off through global configuration, without a code change | Fits when a job is not used by your products or runs at a time that conflicts with your operations. Confirm the exact configuration names and default states for your version in the Fineract documentation before changing them in production. |
| Batch instance for COB | Assigns the Close of Business batch job to a batch-type instance, separate from the instances serving users | Fits any deployment with meaningful account volume, so end-of-day processing does not compete with branch or API traffic. Confirm the batch instance settings and the single-batch recommendation for your release. |
| Remote partitioning of COB | Spreads COB work across worker nodes coordinated through ActiveMQ or Kafka | Fits deployments with millions of accounts where COB can run for several hours on one node. Confirm the broker versions, partitioning settings and message handling your chosen release supports. |
| External business events | Publishes events such as ClientCreated to ActiveMQ, other JMS brokers or Kafka | Fits integrations that must react to Fineract activity. It is disabled by default, so confirm the enabling settings, the event catalog and the broker prerequisites before wiring downstream consumers. |
| Instance type split (read, write, batch) | Separates read traffic, write traffic and batch processing into instances set by environment variables | Fits high-load deployments with read replicas. Confirm which instance types run scheduled jobs, since Liquibase migrations run only on write instances. |
| Job run history review | Shows which jobs ran, when they ran and whether they finished, so operators can confirm COB and job behavior | Fits every production environment. Confirm where run history is exposed in your release and how long it is retained before relying on it for audit evidence. |
How to set up job enablement and COB order before go-live
This sequence turns the scheduler and business-step behavior into a documented, tested baseline for one non-production tenant, so the team knows which jobs run, in what order, how long a close of business takes on representative data, and what normal job history looks like before production.
Inventory jobs in the deployed Fineract version
The platform engineer lists every Quartz-scheduled job and its default state from the Fineract documentation for the exact release you will run, not from memory or a blog post. Record the job names, their schedules, and whether each one touches loans, savings, accounting or notifications. Check the list against the running instance by calling the jobs endpoint in the non-production tenant, and confirm that the names match. The inventory is done when the team can point to a written list that matches what the server reports. Sign-off: the product owner for lending and the platform lead both review the list.
Decide which jobs run on the batch instance
Using the instance model in the Fineract documentation, the architect assigns scheduled jobs to the batch instance and confirms that no read or general write instance runs them unintentionally. Document the reasoning for jobs that involve accounting postings, interest, or the Close of Business Day process, because these are the ones that can lock loans if they overlap. Verify the assignment by checking the environment variables on each deployed instance type and confirming that only the batch instance has the batch role enabled. Sign-off: the platform lead and the operations lead approve the assignment in writing.
Set job enablement in a non-production tenant
In a non-production tenant, the configuration owner changes the job enablement switches in global configuration, one group at a time, following the settings described in the Fineract documentation. Record the before and after values for each switch in the change log, and restart or refresh only as the documentation requires for that release. Confirm the change by reading the global configuration back through the API and comparing it with the approved list. Sign-off: the product owner and the compliance or finance controller approve jobs that affect interest, fees or accounting before they are copied to any other tenant.
Confirm the COB business step order through the API
The developer calls the API that returns the configured Loan COB business steps and their order, then compares that output with the order expected by the business team. Check each step for its purpose, its dependencies, and whether any custom step or processor has been added to the default chain. If the order differs, correct it through the supported configuration path and repeat the read-back. The step is complete when the API output matches the approved order exactly, and the change record names the release and tenant. Sign-off: the lending lead and a senior engineer both confirm the order.
Run COB against representative data and time it
The test lead loads a representative, anonymized data set into the non-production tenant, with account counts, product mix and loan states close to what production will hold, and then runs Close of Business on the batch instance. Record start and end times, the number of accounts processed, and any errors or locked loans. Repeat the run if configuration has changed, so that the timing reflects the final settings. The run is complete when the team has a timed result it can explain, and it reports which steps dominated the elapsed time. Sign-off: the operations lead signs off that the run window is acceptable for the planned schedule.
Record the job run history baseline
After the representative COB run and a normal period of scheduled jobs, the operations engineer exports the job run history through the API and stores it as the baseline. The baseline shows which jobs succeeded, which failed, typical durations, and any repeated errors that need a fix before go-live. Compare future production history against this record during the first weeks of operation. The baseline is done when the file is stored with the release identifier, tenant, configuration version and date. Sign-off: the operations lead and the risk owner accept the baseline as the reference for alerting thresholds.
How COB business steps are ordered through the API
Loan Close of Business runs as a sequence of business steps, and the order of that sequence decides what the batch does to each loan. A step that applies interest, charges or accruals before the data it depends on is ready can post figures that are wrong, and those postings then flow into later steps and into the ledger. Before changing anything, read the current order through the API so you have a baseline to compare against, and record it as part of the environment's configuration.
The order is not fixed for all time. Fineract's business steps can be inspected and reordered through the REST API, but the default sequence is set by the release you run, so an upgrade can add, rename or reorder steps. Treat every Fineract upgrade as a reason to re-read the order and compare it with your baseline. Confirm in the release notes and the Apache Fineract platform documentation which steps the target version ships with and whether any custom order you set is carried across the upgrade or must be reapplied.
Test every order change against the exact version and product mix in use, on a copy of production data where possible. Use a loan with interest, a loan with a due charge, and a loan with a repayment on the same business date, then compare balances and accruals after a COB run with the expected results. Put each change under change control, with a named approver, a written reason, the before and after order, and a rollback plan. A reordering that passes testing on one release can still produce different postings on another, so the test record should name the version it covers.
What goes wrong when jobs overlap, stall or run twice
Background jobs in Fineract fail quietly more often than they fail loudly. The cards below cover the failure modes we see most often in scheduler and COB setups, with the symptom, the likely cause and the first check for each. Where a failure has already left loans locked or COB half-finished, the repair steps belong in the troubleshooting page for stuck loans and failed COB.
COB outlasts the business day
Symptom: Close of Business is still running when branches open, and transactions are blocked or delayed. Likely cause: The Loan COB Spring Batch job can run for several hours on deployments with millions of accounts, and its duration grows with account volume, batch sizing and database contention. Check: Record start and end times of each COB run over several weeks, and compare them with your agreed business day window before changing any setting.
Jobs running on several replicas
Symptom: The same scheduled job appears to run twice, or postings are duplicated after a scale-out or rolling restart. Likely cause: Scheduled jobs are triggered by the instance that hosts them, so a deployment that runs more than one instance with the scheduler enabled on each can fire the same job in parallel. Check: Confirm the instance type and scheduler settings of every replica, and verify that only the intended write or batch instance runs scheduled jobs.
Disabled jobs nobody notices
Symptom: Interest postings, overdue checks or other background work stop, and no error appears in logs or on screens. Likely cause: A job was switched off in global configuration during testing, a maintenance window or an upgrade, and the change was never reversed. Check: Compare the enabled state of every scheduled job against your documented baseline, and review the job run history for jobs that have no recent runs.
Partition workers that go silent
Symptom: A COB run stays at the same progress for a long period, while the coordinating node waits for results that never arrive. Likely cause: With remote partitioning, a worker node stopped or lost its connection to ActiveMQ or Kafka, so its partitions were never completed. Check: Confirm that every worker is connected to the broker it expects, and check the broker for messages that were sent but not consumed.
Locks left after a failed run
Symptom: Specific loans return conflict responses or refuse new transactions the morning after a failed COB. Likely cause: A run that failed or was killed part way through can leave loan locks in place, and those locks are not released automatically. Check: Identify the loans and lock states affected, then follow the troubleshooting page for stuck loans and failed COB rather than clearing locks by hand.
Job changes without a record
Symptom: Job behavior differs between environments, and no one can say when or why it changed. Likely cause: Global configuration switches were edited directly through the API or the admin screens without a change ticket, a peer review or a stored copy of the previous value. Check: Export the global configuration from each environment on a schedule, diff the exports, and require a documented reason for every job-related change.
Checking job run history before and after each upgrade
Run history is the evidence your operations team needs to decide whether a Fineract upgrade left the background work intact. It shows which scheduled jobs ran, when they started and finished, how long the Close of Business run took, and whether COB failed partway through. Without a record taken before the change, the team has no reliable way to say whether a slower or missing job after an upgrade is a regression or simply how the platform behaves now. Treat the baseline as a sign-off artifact, stored with the change record.
Capture the baseline while the current release is still stable and before the upgrade window opens. For a representative period, export the job run history and the COB timings, and note the business dates covered, the number of accounts processed where your reports show it, and any jobs that failed or were retried. Record the exact image tag and database version in the same file so the comparison is tied to a known configuration. After the upgrade, repeat the same export for the same kind of day, such as a month-end, and compare job names, run counts, durations and failure states. Pay particular attention to jobs that your global configuration enables or disables, because a changed default can make a job appear to have stopped when it was never scheduled.
The Fineract README states that official releases are created quarterly, at the end of each quarter, so an upgrade rarely lands on a quiet date by chance. Plan the window around your own month-end and quarter-end calendar, and avoid the first COB run after a release where you cannot compare results with a known good night. Because the exact history views and how long they are retained depend on the Fineract version you run, confirm both in the Apache Fineract platform documentation for that version before you rely on them. If retention is shorter than your comparison window, export the baseline to your own storage before the upgrade starts.
What Apache Fineract scheduler job setup costs and needs from your team
What does Apache Fineract scheduler job setup cost, and what drives the effort?
Scheduler setup cost is driven by the scope agreed in writing, not by a fixed package. Most of the effort sits in four areas: reviewing which Quartz jobs run in your environment, deciding which ones stay enabled, ordering the Loan Close of Business (COB) business steps, and proving the result with job run history. Effort rises with the number of products, custom business steps or processors, the size of your loan book, and how many environments need the same configuration. Recurring cost comes from re-checking job behavior after each Fineract release. DeployOpen does not publish prices. A quote follows from the written scope, so ask for each area to be listed separately.
How long does Fineract scheduler and COB configuration take?
Duration depends on how many jobs and business steps you change, how many tenants share the platform, and how much testing you need against realistic data. The project documentation does not give a fixed setup time, so treat any duration as something to confirm in the written plan. The single largest timing factor is COB runtime itself. The Fineract README notes that the Close of Business Spring Batch job can run for several hours on deployments with millions of accounts, so a full cycle in a large book needs to be measured on production-like data rather than estimated from a demo.
What does the bank's own team need to provide?
Your team needs to supply the business rules that decide which jobs and steps matter, plus access to a production-like environment with representative loan volumes. Operations staff should confirm the end-of-day expectations, holiday calendar and the cut-off time by which COB must finish. Engineers need admin access to global configuration, access to the job run history, and a change process that records each switch. Plan for time from product owners to sign off on business step order, because the sequence affects interest, fees and accounting outcomes.
Can an internal team set up Fineract scheduler jobs without outside help?
Yes, an internal team with Java, Spring Batch and PostgreSQL experience can do this work, provided it has time to read the source and test the results. The risk is not the configuration screens but the knowledge needed to predict what a disabled job or reordered step will change. Ask whether your engineers have run COB on a large dataset, can read the repository code for each job, and can reproduce a failed run. If any answer is no, a fixed-scope engagement can cover the gap, and the team keeps the written runbook afterward.
How do you size the COB window for your loan book?
Size the window by measuring COB on a copy of your data, not by counting accounts. Record the start and end times of each business step from job run history, then add margin for peak month-end volumes and for any remote partitioning across worker nodes. The README states that COB supports remote partitioning coordinated through ActiveMQ or Kafka, so worker count and broker capacity change the window. Confirm the required finish time with operations before testing, because it determines whether you need to tune steps or add capacity.
Which Fineract background jobs can be safely disabled?
No job should be disabled on a general rule. Each Quartz job exists for a reason, and disabling one can stop interest postings, notifications, cleanup or reporting without an obvious error. Decide job by job, using the code for each job and a written record of the business effect. Test every disabled job in a non-production tenant, and confirm which global configuration switches it depends on. Keep a change log so auditors and the next upgrade team can see why each job was enabled or disabled.
How does scheduler job setup change after a Fineract upgrade?
Every upgrade needs a fresh review of job names, default enablement and business step order, because the project releases quarterly and changes can alter behavior. Plan for a regression run of COB on production-like data before each upgrade reaches production. Expect recurring effort for this review, and include it in your support scope. The project documents that end-of-life releases are archived, so confirm the release line you run is still supported before planning the next change.
Limits to confirm in your Fineract version and environment
Scheduler jobs and COB behavior depend on the exact Fineract release, the instance types you deploy, and the message broker you choose. The cards below list what to confirm and who can answer each question, so the design is checked against your version and environment rather than assumed from general guidance.
Scheduled job list and defaults
The set of Quartz jobs, and whether each is enabled by default, can change between releases. Confirm the complete list for the exact version you run, then record which jobs your product design depends on, such as interest posting, overdue checks or COB. Ask the Fineract documentation and your own release notes for any job added or renamed since your last upgrade. Treat a job you have not documented as one you do not yet control.
Job support on read instances
Read instances serve queries on database read replicas and should not run write-side work. Before you assign a job to any instance type, confirm in the Fineract documentation which jobs execute on read, write and batch instances. Ask the project, or test in a non-production tenant, whether a job that writes is blocked or silently runs on the wrong node. Record the answer as part of your instance layout.
COB partitioning for your broker
Remote partitioning of the Close of Business job depends on coordination through ActiveMQ or Kafka. Confirm which broker versions, topics, consumer settings and partition counts the Fineract release supports with your chosen broker. Ask the broker vendor how it handles message ordering, retention and failover for this traffic. Without that confirmation, a worker crash during COB can leave partitions unfinished.
Event publishing and broker dependency
Publishing business events such as ClientCreated to ActiveMQ, another JMS broker or Apache Kafka is disabled by default. Enabling it adds a runtime dependency: if the broker is unavailable, your event consumers and possibly your processing path are affected. Confirm with the Fineract documentation how publishing behaves on broker failure, and ask your broker team to size and monitor the topics before you switch the feature on.
Default development credentials
The README documents a development login of mifos with a default password. That account and its password must be replaced before any environment holds real client data, including staging copies. Confirm how your deployment disables or changes default accounts, and check that OAuth2 or basic authentication settings match your bank's identity policy. Ask your own security or change team to sign off on the account inventory.
Validate changes in a non-production tenant
Changing job enablement, global configuration or COB ordering can alter balances, schedules and accounting on the next business day. Apply each change first in a non-production tenant with representative data, observe the job run history and the resulting ledger entries, and then promote it through your bank's change process. Ask your change board which evidence it requires before approval, and keep the test results with the change record.
How DeployOpen works on this
DeployOpen plans and configures Apache Fineract scheduler jobs and Loan COB business steps as part of a self-hosted deployment in infrastructure you control. The work starts with a written inventory of which jobs run, which are enabled and in what order COB steps execute, then moves to tested changes and documented handover.
How we scope
- We inventory which scheduled jobs and COB business steps your tenants will run, before any setting changes.
- The written scope names each global configuration switch that changes job behavior, with the owner who approves it.
- Scope covers the job run history checks, test tenants and runbooks your operations team will use after go-live.
- Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
How we build
- We configure job enablement through global configuration in a non-production tenant and record each change.
- We define the Loan COB business step order through the API and test it against representative loan volumes.
- We verify job run history and failure handling, including how a failed step is detected and re-run.
- Changes are promoted through your own environments so the same settings are applied deliberately in production.
How we hand over
- You receive a documented job catalog listing each enabled job, its purpose and its configuration owner.
- The handover includes the COB step sequence, the API calls used to read and change it, and rollback steps.
- Operations runbooks cover checking job run history, interpreting errors and escalating to your own engineers.
- Your team reviews and signs off the documentation before the engagement closes.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers after handover.
- Retained support can review job and COB configuration again after each Fineract release or global configuration change.
- Ask any partner to confirm in writing which environments, access and runbooks they need from your team to operate this.
- Pricing follows from the written scope; DeployOpen does not publish a price list.

