Sessions, Tasks or Job Queue, what to use?

I got a question the other day, about executing AL in the background. We now have several options for doing that, but what should you choose? Check out the video for my perspective:

https://youtu.be/CdxVtGbalik

When you need to run code in the background in Business Central, you’re faced with several options: Job Queue, Task Scheduler, and Start Session. In this video, Erik breaks down each of these mechanisms, explains how they relate to one another, and shares practical guidance on when to use each one.

A Brief History: The NAS

To understand where we are today, it helps to look back. In the old NAV days, we eventually got the NAS (NAV Application Server). The NAS was essentially a client without a UI that would run a specific piece of code in Codeunit 1 when it started up. This gave us the ability to run things in the background, but communication was primitive — you’d write instructions into a table, hope the NAS would pick them up, and there wasn’t a great way to get feedback on what happened. That’s where we started. Today, we have several well-defined ways to execute code in the background.

The Job Queue: A Pretty UI on Top of Tasks

The Job Queue is often the first thing people think of for background processing, but here’s the key insight: the Job Queue is not a separate execution mechanism. It’s a user-friendly interface that allows users to define and control background tasks. Under the hood, the Job Queue runs as scheduled tasks.

You can verify this by looking at the Scheduled Task list in Business Central. There you’ll see entries that all run Codeunit 448 (the Job Queue Dispatcher), with Codeunit 450 (the Job Queue Error Handler) set as the failure codeunit. The Job Queue Dispatcher looks at the job queue entries and determines which codeunit to run with which parameters.

So if you want to schedule something from code, you don’t need the Job Queue unless you specifically want your users to be able to control the execution going forward. If user control isn’t a requirement, you can go directly to the Task Scheduler.

The Task Scheduler: Deferred Background Execution

The Task Scheduler lets you create a task programmatically. You pass in a codeunit to run, an optional failure codeunit, a company name, a “not before” datetime, and a record ID as data.

A few important characteristics of scheduled tasks:

  • Company context: You can specify which company the task runs in. This is a great trick — if you need to do something in another company, instead of dealing with the headaches of ChangeCompany, schedule it as a task in that other company.
  • “Not before” timing: There’s a “not before” datetime, but no guarantee it will run at exactly that time. It simply won’t run before that time.
  • Retry logic: If the task can’t run (for example, because an upgrade is in progress), it will retry — up to 99 times in the cloud and 9 times on-prem by default.
  • Failure handling: If the main codeunit fails, the transaction rolls back, the scheduled task entry is deleted, and the failure codeunit runs instead.
  • Concurrency limit: There’s a maximum of 3 concurrent running scheduled tasks per environment.

Erik uses scheduled tasks in two main scenarios:

  1. Timed execution: When something needs to run at a specific time, like “tonight at 10 PM.”
  2. Low-priority work: When something needs to happen but isn’t urgent. You schedule it for “now” or “30 seconds from now,” and it will run when resources are available — which might be immediately, or might be 5–10 minutes later if the system is busy.

Start Session: Immediate Background Execution

The StartSession function starts a background session right away. You pass a codeunit, a company, and a record. You also get a session ID back so you can call StopSession later if needed.

In reality, the Task Scheduler is just a timed way of doing a StartSession — the very first thing that happens when a scheduled task fires is that it starts a session.

Erik uses StartSession when something needs to happen concurrently with the current process. Here are two real-world examples:

  • Parallel document upload: In the e-foqus SharePoint Connector, when posting runs, an event subscriber calls StartSession to upload documents to SharePoint in parallel. The upload doesn’t block or slow down the posting process because it runs in a separate session.
  • Massive parallel processing: In the e-foqus Cloud Replicator (which replicates Business Central data to a cloud data warehouse), users can configure how many parallel sessions to use — sometimes running 60+ sessions simultaneously to pump data into a cloud database.

The operational limit for background sessions is 100 per tenant, and a session always runs on the same service tier where it was started.

Common Considerations for All Background Execution

All of these approaches open a new session, which means the full session lifecycle applies: the company opens, all OnOpen triggers fire, and so on. Critically, you cannot show UI in a background session. If you have code that sometimes runs interactively and sometimes in the background, you need to handle this. The recommended approach is to use GuiAllowed():

pageextension 50100 CustomerListExt extends "Customer List"
{
    trigger OnOpenPage();
    begin
        if GuiAllowed()
            // Show UI elements, confirmations, pages, etc.
    end;
}

GuiAllowed() returns true only when there’s actually a GUI present. In a background session, it returns false. There’s also the CurrentClientType function if you need to distinguish between different client types — API calls, web services, SOAP, the web client, and so on — but for most background vs. foreground decisions, GuiAllowed() is your friend.

Page Background Tasks: A Special Case

There’s one more option worth mentioning: Page Background Tasks. Despite the name including “task,” they behave more like sessions. Page Background Tasks are specifically designed to offload work like fetching data from web services so that a page doesn’t block while waiting. When the data returns, you can update a FactBox or other page element. This is a very specific mechanism for a very specific use case, and Erik has covered it in a separate video on the channel.

Summary: When to Use What

  • Job Queue: Use when you want users to be able to configure, schedule, and monitor recurring background processes through a UI. Under the hood, it’s just scheduled tasks.
  • Task Scheduler: Use for deferred or low-priority background work, timed execution, or when you need to run code in a different company context. Be aware of the 3 concurrent task limit.
  • Start Session: Use when you need immediate parallel execution — something that should happen right now alongside the current process. Supports up to 100 background sessions per tenant.
  • Page Background Task: Use specifically for offloading data retrieval on pages so the UI doesn’t block.

Understanding these distinctions helps you choose the right tool for the job and avoid over-engineering or under-engineering your background processing solutions in Business Central.