Hi everyone,
I have a requirement where I need to process a large number of records using an OutSystems Timer.
For example, suppose there are 1 million records in a database, and each record needs to be processed by a Server Action.
I don't want to process all records in a single Timer execution because it may cause timeout, high memory usage, or performance issues.
I am thinking of processing the records in batches, for example:
If possible, could someone please share a sample OML/module implementation demonstrating this approach?
Hi @Anushka singh ,
Yes, processing millions of records in batches would be a good and scalable approach.
You can implement the processing flow as follows:
This approach provides scalability, controlled database load, retry capability, fault isolation, and protection against user request timeouts, especially when processing millions of records.Let us know if you want more information.RegardsDeepa
hello @Deepa Tiwari,i understood your process and earlier i was built same logic but it is not working can so you give me oml file this will help me a lot.
Hello @Anushka singh,
Along with my colleagues answers, I’ve attached an OML as an example for your reference.
Here is a more in-depth article you can follow that should answer most of your questions: How to Manage Heavy Timers in OutSystems .
To answer your questions briefly:
You already described the recommended approach: process the records in manageable batches instead of handling everything in a single Timer execution.
Define a configurable batch size, and use appropriate filtering and deterministic sorting in the Aggregate. Each Timer execution should retrieve and process only the next eligible batch.
Aggregates are generally easier to understand and maintain. I would use SQL only when the query is too complex or cannot be efficiently implemented with an Aggregate.
If processed records are excluded through a status filter, you may not need StartIndex at all. You can repeatedly fetch the first batch of unprocessed records.
The safest approach is to track the processing status on each record, for example Pending, Processing, Processed, or Failed. Fetch only eligible records and update the status after processing.
Alternatively, you can maintain a separate execution entity containing information such as:
You can then retrieve the last processed ID when the Timer starts, filter for records with a greater ID, and sort by ID ascending. However, be careful with this approach because advancing the last processed ID could cause failed records to be skipped unless they are tracked separately for retry.
Usually, one failed record should not stop the entire batch. Catch the error, record the failure, and continue processing the remaining records.
Depending on the reporting requirements, you can:
Retrying failed records or generating reports should preferably be handled by a separate action or Timer, triggered only when necessary.
6. Are there any best practices regarding Timer timeout, batch size, and transaction handling?
You can read this: Optimizing OutSystems timers according best practices
Hello.
Large timers and batch processing is a topic well-documented so I don't need to repeat what others have said.
Just a note on Batch Size. It will depend a lot on the volume of work. Optimize memory taken and number of reads done.
Trial and error will get you there and the configurable BatchSize property allows you to adjust it at runtime (at least in O11).
From experience, I usually do 500 to 3000. The timer logic you see on the links has a loop to fetch more records in one execution so it can still do millions in under 20 minutes.