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
- 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.
- Bucketing — daily buckets near-term, weekly beyond, monthly far out. Nobody needs day-level precision six months out.
- Horizon limits — don’t calculate beyond the planning horizon.
- In-memory — the modern answer; aggregate on the fly in a columnar store. SAP’s aATP does this on HANA.
- Caching with careful invalidation — dangerous. A stale ATP over-promises. Only cache within a single document’s processing.
- 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
- ATP is time-phased and cumulative. A single “available quantity” number is wrong.
- Document the check scope. Every element included or excluded is a business decision with revenue consequences.
- Maintain an aggregated time series rather than scanning source documents on every check.
- Choose your concurrency strategy deliberately and write it down.
- Confirmed quantity and date live on the schedule line, not the item.
- 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.
- Log every ATP result with its inputs. “Why did it confirm that date?” is asked constantly, and without the log you cannot answer.