Acumatica's Advanced Planning and Scheduling (APS) module gives you a choice that sounds academic and is anything but: schedule against infinite capacity or finite capacity. Pick wrong and you either get promise dates nobody can hit, or a scheduling model so brittle the planners abandon it and go back to Excel. I've seen both failure modes on real implementations, so here's the practical breakdown.
What the two modes actually do
Infinite scheduling ignores work center load. Each production order is scheduled by exploding its routing, applying operation times (setup + run × quantity + queue and move times), and placing operations on the calendar backward from the need date or forward from the start date. Two hundred orders can land on the same work center on the same Tuesday; the schedule doesn't care. Overload only becomes visible when you look at capacity screens or dashboards.
Finite scheduling respects capacity. Each work center has a defined capacity from its calendar and shifts, and the scheduler places operations into available slots, pushing work out when a resource is full. The schedule is feasible by construction — but only as feasible as your data is honest.
The data tax of finite scheduling
Finite scheduling is a data-quality amplifier. It needs, at minimum:
- Accurate routing times. If your run time says 2 minutes per unit and reality is 5, finite scheduling confidently builds an impossible plan and defends it with math.
- Real work center calendars. Shifts, breaks, planned maintenance, actual number of machines/operators per work center. A work center defined as 2 machines when one is down for a month poisons everything downstream.
- Honest queue and move times. These buffers are where most shops hide chaos. Too small and every schedule is fragile; too large and lead times balloon.
- Timely production reporting. Finite scheduling replans from current state. If operators report labor a day late, the scheduler thinks yesterday's work still needs capacity today.
My honest advice: if the client can't keep routings within ±20% of reality and won't report production daily, implement infinite scheduling with capacity visibility, and revisit finite in a year. Infinite with a planner reading the load charts beats finite with garbage data every time.
A middle path that has worked well for me: run infinite scheduling but build a Generic Inquiry over work center load per week (planned hours vs calendar capacity), pinned to a dashboard. Planners get overload warnings without the data burden of full finite APS. Half my manufacturing clients never need to go further.
Scheduling mechanics worth knowing
A few behaviors that surprise people on the Production Order Maintenance and APS screens:
- Backward vs forward. Backward scheduling from the constraint (need) date is the default planners expect, but when the computed start lands in the past, the scheduler flips to forward-from-today, and your promised date moves. Watch for orders whose scheduled end silently exceeds the sales order ship date after a reschedule.
- Firm vs scheduled orders. Firming a production order pins its dates so the next scheduling run doesn't move it. Planners should firm the near-term horizon (this week, next week) and let the engine own everything beyond. If nobody firms anything, every reschedule reshuffles tomorrow's dispatch list and the shop floor stops trusting the system.
- Dispatch priority. When capacity is contested, order priority and dates decide who gets the slot. If everything is priority 1 — and left to users, everything becomes priority 1 — finite scheduling degenerates to date order.
Reading schedule data programmatically
Clients frequently want the schedule outside Acumatica — a TV dashboard in the shop, a daily email. The operation schedule lives in the production order operation DACs, and a lightweight BQL read from a scheduled graph does the job:
public IEnumerable GetTodaysDispatch(PXGraph graph, string workCenterID)
{
var today = graph.Accessinfo.BusinessDate;
return SelectFrom<AMProdOper>
.InnerJoin<AMProdItem>
.On<AMProdOper.orderType.IsEqual<AMProdItem.orderType>
.And<AMProdOper.prodOrdID.IsEqual<AMProdItem.prodOrdID>>>
.Where<AMProdOper.wcID.IsEqual<@P.AsString>
.And<AMProdOper.startDate.IsLessEqual<@P.AsDateTime>>
.And<AMProdItem.statusID.IsEqual<ProductionOrderStatus.released>>>
.OrderBy<Asc<AMProdOper.startDate>>
.View.Select(graph, workCenterID, today);
}
I usually expose this through a Generic Inquiry plus the REST API rather than custom code when the shape is simple — but once you need cross-order sequencing logic or color-coding rules, a small graph extension is cleaner than a GI with fifteen calculated fields.
Choosing for real shops
Job shops with high routing variety and honest time standards get the most from finite scheduling — capacity is genuinely the constraint and the feasibility guarantee earns its keep. Repetitive manufacturers with stable takt-like flow often do fine on infinite plus load visibility, because their constraint is material, not machine time. And any shop where production reporting lags a shift behind reality should fix reporting first; no scheduling algorithm outruns stale inputs.
Wrapping up
Finite scheduling is not an upgrade of infinite scheduling — it's a different contract with your data. Infinite says "here's when work should happen, you manage the overload." Finite says "give me perfect inputs and I'll give you a feasible plan." Choose based on the data discipline the shop actually has, not the one the sales demo assumed, and remember the middle path: infinite scheduling with capacity dashboards covers more real factories than either extreme.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.