Availability Check and ATP

“Can I promise this to the customer, and when?” — the single most performance-sensitive question in an ERP, asked on every order line, in real time, while the customer waits.

The three questions

Question Term
Is it physically here right now? On-hand stock
Can I promise it, given commitments and incoming supply? ATP — Available to Promise
Could I make it if I had to? CTP — Capable to Promise (checks capacity too)

The ATP calculation

Start:  on-hand unrestricted stock
     +  planned receipts within the horizon
          purchase orders (confirmed delivery date)
          production orders
          planned orders (if configured to count — usually not, they're not firm)
          stock transfers in transit
     −  planned issues
          confirmed sales orders
          deliveries not yet goods-issued
          production reservations
          stock transfers out
     −  safety stock (if excluded from ATP — usually yes)
─────────────────────────────────────────────────────
=  ATP quantity, time-phased

Time-phased, not a single number

Date       Receipts  Issues  Balance  Cumulative ATP
Today           —      —       500          500
15 Mar          —    (300)     200          200
18 Mar        400       —      600          600
22 Mar          —    (500)     100          100
28 Mar        250       —      350          350

A customer wanting 400 on 22 March cannot have it (only 100 available then) but can have it on 28 March. That’s the answer ATP must produce — not “no”.

Cumulative ATP is the correct basis: the minimum available from the requested date forward, so you never promise stock that’s already committed to an earlier order.

Check scope configuration

What counts is configurable, and each choice is a business decision:

Element Include? Consideration
Safety stock Usually no It’s a buffer, not sellable
Stock in quality inspection Usually no Might fail
Blocked stock No Not usable
Purchase orders Yes But how reliable is the vendor’s date?
Purchase requisitions Usually no Not firm
Planned orders Usually no Not firm
Production orders Yes Firm
Stock in transit Yes It’s arriving
Deliveries not yet issued Yes, as an issue Already committed
Consignment stock at customer No Already at the customer
Returns awaiting inspection No Condition unknown

Replenishment lead time (RLT): many configurations say “beyond N days, always confirm” — because within the replenishment lead time you can always procure more. This dramatically reduces “not available” answers on distant dates, but it means you’re promising against your own supply reliability.

Check modes

Individual requirements

Each sales order line creates its own requirement record. Precise, traceable, heavy on volume. Used for high-value or make-to-order items.

Summarised requirements

Requirements aggregated per material/plant/day. Much lighter, loses per-order traceability. Used for high-volume, low-value consumer goods.

Configured per material (the “availability check group”). Getting this wrong on a fast-moving item can generate millions of requirement records.

Allocation and rationing

When supply is short, who gets it?

Product allocation / fair share

Product X, April supply: 10,000 units
Allocation:
  Key account A   4,000  (40%)
  Key account B   3,000  (30%)
  Distributors    2,000  (20%)
  Spot market     1,000  (10%)

Orders check against both ATP and their allocation bucket. This runs constantly in semiconductors, pharma during shortages, and consumer goods at launch.

Backorder processing

When supply arrives, existing unconfirmed orders are re-checked and re-confirmed. Rules matter enormously:

Rule Effect
FCFS — first come first served Fair, simple, may starve strategic customers
Priority by customer Key accounts first
Priority by margin Profit-maximising
Delivery date Earliest required date wins
Fair share / proportional Everyone gets a percentage

Rescheduling re-runs this across all open orders periodically. It can remove confirmation from an order that already had it, which is why it is usually run with careful rules and a review step — telling a customer their confirmed date has slipped is a phone call, not an email.

Multi-plant / global ATP

Customer orders 500 units:
  Plant DHK1:   200 available
  Plant CTG1:   400 available
  Plant DXB1: 1,000 available

Options:
  a) Split: 200 from DHK1 + 300 from CTG1
  b) All from DXB1 (single shipment, longer transit, possible customs)
  c) Transfer stock to DHK1, then ship

The decision needs: transport cost, transit time, customs and duty, whether the customer accepts split deliveries, and legal-entity implications (a cross-entity source becomes an intercompany sale). This is where global ATP tools (SAP aATP/gATP, o9, Blue Yonder) earn their money, and why simple ATP stops at one plant.

Performance — the real engineering problem

ATP is called:

  • On every order line entry, interactively (users expect <1 second)
  • On every order change
  • On delivery creation
  • In batch during rescheduling (millions of lines)

Naive implementation: scan all stock, all POs, all orders for the material. At scale this is fatal.

Techniques

  1. Aggregated ATP time series — maintain a per (material, plant, date) summary table updated transactionally on every relevant document change. Read is then a single indexed range scan.
  2. Bucketing — daily buckets near-term, weekly beyond, monthly far out. Nobody needs day-level precision six months out.
  3. Horizon limits — don’t calculate beyond the planning horizon.
  4. In-memory — the modern answer; aggregate on the fly in a columnar store. SAP’s aATP does this on HANA.
  5. Caching with careful invalidation — dangerous. A stale ATP over-promises. Only cache within a single document’s processing.
  6. Optimistic check + confirm — quick approximate check during entry, authoritative check at save.

The concurrency problem

Stock: 100 units
User A checks: 100 available → confirms 80
User B checks: 100 available → confirms 80   (checked before A saved)
Both save. 160 confirmed, 100 exist.

Solutions:

  • Lock the material/plant during check + confirm. Correct, and a throughput bottleneck on hot items.
  • Optimistic: check at save, re-verify, fail if over-committed. Better throughput, occasional user-visible failure.
  • Reservation-based: the check creates a short-lived reservation immediately, which either converts on save or expires. This is what high-volume e-commerce does.
  • Accept over-commitment and resolve in backorder processing. Common in consumer goods where a small overbooking is cheaper than a lock.

There is no free answer — it’s a deliberate business trade-off between never disappointing a customer and order-entry throughput. Make it explicitly, and document which one you chose.

ATP vs delivery scheduling

ATP says when material is available. Delivery scheduling works out when the customer actually receives it:

Material availability date        18 March
+ Pick/pack time (2 days)         20 March
+ Loading time (0.5 day)          20 March
+ Transit time (4 days)           24 March
= Confirmed delivery date         24 March

Backward scheduling from the customer’s requested date: if the result is in the past, switch to forward scheduling from today and confirm the earliest possible date. All of it on the factory calendar and the route’s transit calendar, not calendar days. See Periods and Calendars.

Design rules

  1. ATP is time-phased and cumulative. A single “available quantity” number is wrong.
  2. Document the check scope. Every element included or excluded is a business decision with revenue consequences.
  3. Maintain an aggregated time series rather than scanning source documents on every check.
  4. Choose your concurrency strategy deliberately and write it down.
  5. Confirmed quantity and date live on the schedule line, not the item.
  6. Never let ATP block order entry when the ATP service is down. Degrade to “unconfirmed, to be checked” rather than refusing orders — an outage that stops sales is worse than one that delays confirmations.
  7. Log every ATP result with its inputs. “Why did it confirm that date?” is asked constantly, and without the log you cannot answer.

Next