Recursive programming is hard in AL, even for Microsoft!

Today, we tackle a support ticket about an out-of-memory error when posting in the Item Journal. Check it out:

https://youtu.be/weIU8anOE0I

This video explores a real-world support ticket that exposed an important limitation in Business Central’s AL runtime: the call stack depth. What starts as a customer error during inventory posting leads to an investigation of recursive function calls in Microsoft’s own base application code, and reveals that the call stack limit is surprisingly shallow at roughly 998-1000 calls deep.

The Support Ticket

The story begins with a support ticket where a customer was trying to post a positive adjustment to inventory. They received this error:

“There’s insufficient memory to execute this function. This can be caused by recursive function calls. Contact your system administrator.”

The call stack attached to the ticket showed a clear repeating pattern:

  • CheckCyclicFwdToSingleAppliedEntries
  • CheckCyclicFwdToAppliedInboundEntries
  • CheckCyclicFwdToAppliedEntries

These six lines of function calls were repeating over and over again, forming a recursive cycle.

Understanding the Recursive Pattern

The code lives in Table 339 (Item Application Entry). Tracing through the calls reveals the cycle:

  1. CheckCyclicFwdToAppliedInboundEntries — calls → ForwardToSingle
  2. ForwardToSingle — calls → AppliedOutbound
  3. AppliedOutbound — calls → OutboundEntry
  4. Which eventually calls back to → AppliedInbound

This creates a recursive loop. The purpose of this code is to detect cyclic item application entries — essentially checking that items applied to each other don’t form an endless loop. The recursion itself isn’t inherently wrong; it’s a legitimate approach to walking a graph of applied entries. But in this customer’s case, there were enough connected documents that the check never completed before hitting the call stack limit.

How Deep Is the AL Call Stack?

To determine the actual call stack depth limit, a simple test was constructed:

var
    Depth: Integer; // Global variable

procedure DeepCall()
begin
    Depth += 1;
    DeepCall();
end;

This straightforward recursive function increments a counter on each call, eventually hitting the limit. Running this test on Business Central version 27 revealed:

  • The function reached a depth of 997 before crashing
  • The call stack contained 998 calls
  • The actual limit is approximately 998-1000 calls deep

The same “insufficient memory to execute this function” error appeared — identical to what the customer experienced.

Why 1,000 Calls Isn’t Enough

A thousand calls may sound like a lot, but when you consider the recursive pattern in the item application entry check, each document consumes approximately six levels of the call stack. Simple math tells us:

1,000 ÷ 6 ≈ 166 documents

In this customer’s case, it only took around 200 open documents to exhaust the call stack. This was a high-volume environment with lots of assembly orders being created and posted to match outgoing shipments — not an unreasonable scenario at all.

Tail Call Optimization: A Solution That Doesn’t Exist in AL

In many programming languages, there’s a technique called tail call optimization (TCO) that can solve this problem. A tail call occurs when a recursive function’s last action is the recursive call itself — meaning there’s nothing left to do after the call returns. In such cases, the runtime can reuse the current stack frame instead of allocating a new one, effectively turning recursion into iteration.

The recursive calls in the item application entry code are actually tail calls — at the point where the recursive call is made, nothing from the current stack frame is needed anymore. The stack could be freed up, making the recursion essentially free from a memory perspective.

However, tail call optimization is not something Microsoft has implemented in the AL runtime. Every recursive call allocates a new stack frame regardless of whether the previous one is still needed.

Conclusion

The AL call stack in Business Central is limited to approximately 998-1000 calls deep. While this might seem sufficient for most scenarios, recursive patterns in the base application — particularly in areas like item application entry validation — can consume multiple stack frames per logical operation. In high-volume environments with hundreds of interconnected documents, this limit is surprisingly easy to hit. A call stack depth of 1,000 in 2026 is remarkably shallow, and the absence of tail call optimization in the AL runtime makes recursive programming patterns particularly risky. If you’re designing solutions that involve recursion, be mindful of this hard limit and consider iterative approaches where possible.