User Exits
ABAP Developmentadvanced

User Exits Part 8: Performance Risks in User Exits

Key takeaway

Find and fix performance problems caused by user exits: how often SD exits run, SELECTs in item loops, repeated reads of the same master data, reading reference documents, buffering per document, and measuring with ST05 and SAT in mass processing (VL10, VF04, BAPIs).

Explanation

📌 KEY POINTS
✅ SD exits run far more often than one might expect: MOVE_FIELD exits per field/item change, pricing exits per item and condition, save exits per document.

✅ The biggest risk is database access inside item loops or frequently called FORMs.

✅ Fix with guards, using data already in memory (XVBAP, XVBPA, KOMK/KOMP), and keyed buffers per document.

⚠️ Performance problems in exits often appear only in mass processing (VL10, VF04, EDI) — test with production-like volume.

━━━━━━━━━━━━━━━━━━━━
▶ WHERE WE ARE

Part 7 covered correctness. Now speed: exits run in the heart of SD transactions and mass runs.

━━━━━━━━━━━━━━━━━━━━
▶ 1. HOW OFTEN DO EXITS RUN?

  • USEREXIT_MOVE_FIELD_TO_VBAP: every time an item is processed (including copying and re-determination).
  • Pricing exits: per item and repeatedly during pricing (new pricing, changes).
  • Save exits: per document, but they often loop over all items.

Use SAT or a breakpoint counter to see real numbers.

━━━━━━━━━━━━━━━━━━━━
▶ 2. TYPICAL PROBLEMS

  • SELECT SINGLE from KNVV/MARA/Z tables for every item.
  • SELECT without full key on large tables (VBAP, VBFA).
  • Reading the same customer data in header and item exits repeatedly.
  • Calling function modules that read a lot internally, per item.

━━━━━━━━━━━━━━━━━━━━
▶ 3. FIXES

  • Guard conditions first (Part 7).
  • Use what's in memory: XVBPA for partners, XVBAP for items, VBKD for business data, KOMK/KOMP in pricing.
  • Keyed buffers (hashed tables) with refresh per document.
  • FOR ALL ENTRIES / JOINs once per document instead of reads per item.
  • Move heavy checks from item-level to save time.

━━━━━━━━━━━━━━━━━━━━
▶ 4. MEASURE

  • ST05: SQL trace on a representative order; look at identical selects and records.
  • SAT: runtime per program/FORM; compare with exit logic deactivated (e.g. via a feature flag).
  • For mass runs: trace a job run with SM50/ST05 for a limited time; check VL10/VF04 runtimes before/after.

━━━━━━━━━━━━━━━━━━━━
▶ 5. PREVENT

Performance review for every exit change; guideline "no SELECT in item exits without buffer".

━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP

  1. Trace VA01 with 100 items using ST05; identify statements from your exits.
  2. Replace per-item reads with a buffer (code example).
  3. Re-trace and compare the number of statements and runtime.

✅ CHECKPOINT: your exits add minimal runtime even in mass processing.

Code example

ABAP Code
* ===== BEFORE: per-item SELECT in an item-level exit =====* FORM userexit_move_field_to_vbap.*   SELECT SINGLE kdgrp FROM knvv INTO lv_kdgrp*     WHERE kunnr = vbak-kunnr AND vkorg = vbak-vkorg*       AND vtweg = vbak-vtweg AND spart = vbak-spart.   " same row read for every item!*   ...* ENDFORM. * ===== AFTER: data from memory or a buffer per document =====* MV45ATZZDATA: zz_buf_kunnr TYPE kunnr,      zz_buf_kdgrp TYPE kdgrp. * MV45AFZZFORM userexit_move_field_to_vbap.  CHECK vbak-auart = 'ZOR'.                           " guard * 1) Prefer data already available: business data of the header  IF vbkd-kdgrp IS NOT INITIAL.    vbap-zzkdgrp = vbkd-kdgrp.    EXIT.  ENDIF. * 2) Otherwise read once per customer, not per item  IF zz_buf_kunnr <> vbak-kunnr.    SELECT SINGLE kdgrp FROM knvv INTO zz_buf_kdgrp      WHERE kunnr = vbak-kunnr AND vkorg = vbak-vkorg        AND vtweg = vbak-vtweg AND spart = vbak-spart.    zz_buf_kunnr = vbak-kunnr.  ENDIF.  vbap-zzkdgrp = zz_buf_kdgrp.ENDFORM. * ===== Measuring =====* ST05  : activate SQL trace -> run VA01 with 100 items -> display, summarize identical selects* SAT   : measure VA01 / VF04 run, compare with feature flag off

Real project scenario

Nightly EDI order creation (8,000 orders) took 5 hours and started overlapping with morning deliveries. ST05 on a sample showed 1.2 million SELECTs on KNVV and a Z pricing table from item-level user exits.
Using VBKD data and buffers per customer reduced the statements by 95% and the run time to 70 minutes. Performance tracing became mandatory for every exit change in the order-to-cash area.

Common mistakes

  • SELECT in item-level exits without buffering.
  • Reading data already available in X tables or VBKD.
  • Unkeyed buffers that keep data of the previous document.
  • Testing only single orders, not mass runs.
  • Heavy checks in frequently called MOVE_FIELD exits.

Best practices

  • Know the call frequency of each exit.
  • Guard first, use memory data second, buffer third.
  • Key buffers by customer/document and refresh them.
  • Measure with ST05/SAT and in mass runs.
  • Performance review as part of every exit change.

Interview angle

Questions: "An order takes long to save after a user-exit change. How do you analyse it?", "How do you avoid performance issues in user exits?"
Strong answer: understand exit call frequency; ST05 for identical selects and SAT for runtime distribution, compare with logic disabled; fix with guards, data from XVBAP/XVBPA/VBKD/KOMP, keyed buffers per document, set-based reads, moving heavy checks to save; test mass runs (EDI, VL10, VF04).

Practice this lesson

Quick check

1. A save exit reads material data per item. What is the best optimisation?

2. Which tool best shows identical SELECTs caused by a user exit?

3. Why is data from VBKD or XVBPA preferred over new SELECTs in SD exits?

Interview questions

1. Why is SELECT inside LOOP dangerous in user exits?

Answer it in your own words first, then compare.

2. A save exit read material master data once for every sales order item. What is the impact and how do you optimise it?

Answer it in your own words first, then compare.

Practice more with Interview AI →

Reference-verified: the steps are checked against official SAP documentation and tutorials, and object and field names in the sample code are checked for consistency. The code has not been compiled or run on an SAP system by ERPClimb. Syntax marked release-dependent varies by SAP release, so check it in your own system.

More lessons in this topic

Interview questions on this topic

Related SAP topics