BAdI
ABAP Developmentadvanced

BAdI Part 9: Performance and Database Access in BAdIs

Key takeaway

Keep BAdI implementations fast: how often methods are called (per item, per field change, per screen round trip), guard conditions, buffering with keyed tables per document, avoiding SELECT in loops and BAPI calls, instance creation modes, and measuring with ST05 and SAT.

Explanation

📌 KEY POINTS
✅ BAdI methods can be called far more often than you expect — per item, per field change, on every Enter.

✅ Guard conditions first, then use data from parameters, then buffer database reads by key.

✅ Measure: ST05 (SQL trace) and SAT (runtime analysis) with realistic document sizes.

⚠️ Buffers in static attributes live for the whole session — key them and refresh them, or you show stale or wrong data.

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

Part 8 structured the code. Now: make sure it does not slow down the transaction.

━━━━━━━━━━━━━━━━━━━━
▶ 1. HOW OFTEN IS IT CALLED?

  • PROCESS_ITEM in ME_PROCESS_PO_CUST runs for each item on every change/check.
  • Pricing and delivery BAdIs run per item and during copy, repricing and output.
  • Mass programs (MASS, uploads, VL10, billing runs) call them thousands of times.

Use SAT or a counter in the debugger to see the real number.

━━━━━━━━━━━━━━━━━━━━
▶ 2. GUARD CONDITIONS

Exit immediately when the document type, org unit or field is irrelevant: the cheapest code is code that doesn't run.

━━━━━━━━━━━━━━━━━━━━
▶ 3. USE WHAT YOU GET

Parameters and objects often contain the data you want to SELECT (header data, item data, partner data). Read them before going to the database.

━━━━━━━━━━━━━━━━━━━━
▶ 4. BUFFER BY KEY

  • Hashed table keyed by the lookup key (material, customer).
  • Instance attributes if the BAdI instance is reused (new BAdI instance creation mode "reuse") or a separate buffer class with static data.
  • Refresh when the document changes (store the document number; clear if different).
  • Prefer SAP buffered tables and standard read FMs with internal buffering where available.

━━━━━━━━━━━━━━━━━━━━
▶ 5. AVOID

  • SELECT inside loops over items.
  • BAPI calls or RFC per item.
  • Reading large tables without WHERE on key fields.
  • Expensive checks in methods called on every Enter when a check at save is enough.

━━━━━━━━━━━━━━━━━━━━
▶ 6. MEASURE

  • ST05: count identical statements (Summarize/"Identical Selects").
  • SAT: time spent in your class vs standard.
  • Compare with/without the implementation (deactivate in test system).

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

  1. Trace ME21N with 50 items and your BAdI active using ST05.
  2. Identify identical SELECTs and add a keyed buffer.
  3. Re-trace and document the improvement.

✅ CHECKPOINT: your BAdI code runs only when needed and reads each record at most once.

Code example

ABAP Code
* ===== Buffered vendor data for a PO BAdI =====CLASS zcl_vendor_buffer DEFINITION PUBLIC FINAL CREATE PUBLIC.  PUBLIC SECTION.    CLASS-METHODS get_block_flag      IMPORTING iv_lifnr        TYPE lifnr                iv_ekorg        TYPE ekorg      RETURNING VALUE(rv_block) TYPE sperm_m.  PRIVATE SECTION.    TYPES: BEGIN OF ty_buf,             lifnr TYPE lifnr,             ekorg TYPE ekorg,             sperm TYPE sperm_m,           END OF ty_buf.    CLASS-DATA gt_buf TYPE HASHED TABLE OF ty_buf WITH UNIQUE KEY lifnr ekorg.ENDCLASS. CLASS zcl_vendor_buffer IMPLEMENTATION.  METHOD get_block_flag.    DATA ls_buf TYPE ty_buf.    READ TABLE gt_buf INTO ls_buf WITH TABLE KEY lifnr = iv_lifnr ekorg = iv_ekorg.    IF sy-subrc <> 0.      ls_buf-lifnr = iv_lifnr.      ls_buf-ekorg = iv_ekorg.      SELECT SINGLE sperm FROM lfm1 INTO ls_buf-sperm        WHERE lifnr = iv_lifnr AND ekorg = iv_ekorg.      INSERT ls_buf INTO TABLE gt_buf.         " one DB read per vendor/org    ENDIF.    rv_block = ls_buf-sperm.  ENDMETHOD.ENDCLASS. * ===== BAdI method: guard first, buffer second =====CLASS zcl_im_po_vendor DEFINITION PUBLIC FINAL CREATE PUBLIC.  PUBLIC SECTION.    INTERFACES if_ex_me_process_po_cust.ENDCLASS. CLASS zcl_im_po_vendor IMPLEMENTATION.  METHOD if_ex_me_process_po_cust~check.    DATA ls_header TYPE mepoheader.    ls_header = im_header->get_data( ).     IF ls_header-bsart <> 'ZNB'.                " guard: only relevant PO type      RETURN.    ENDIF.    IF zcl_vendor_buffer=>get_block_flag( iv_lifnr = ls_header-lifnr                                          iv_ekorg = ls_header-ekorg ) = 'X'.      ch_failed = abap_true.    ENDIF.  ENDMETHOD.ENDCLASS.* Checked once in CHECK (at save/check), not in PROCESS_ITEM for every item.

Real project scenario

A PO BAdI validated vendor, material and budget data in PROCESS_ITEM. For a 300-item framework order, ST05 showed 9,000 SELECTs, and users waited 40 seconds after every Enter.
The team moved vendor checks to CHECK (once per PO), used item data already provided by the item objects, and buffered material data by key. The wait dropped to 3 seconds, and the budget check was moved to save time only.

Common mistakes

  • Heavy checks in methods called on every Enter.
  • SELECT per item without buffering.
  • Static buffers never refreshed.
  • BAPI/RFC calls inside BAdI loops.
  • Not measuring with realistic document sizes.

Best practices

  • Know the call frequency of each method.
  • Guard conditions at the top.
  • Use parameter data before the database.
  • Keyed, refreshed buffers.
  • Measure with ST05/SAT before and after.

Interview angle

Questions: "How do you make a BAdI implementation performant?", "How do you analyse BAdI performance?"
Strong answer: understand call frequency (per item/Enter/mass runs), guard conditions, use parameters' data, keyed buffers with refresh logic, avoid SELECT/BAPI in loops, put expensive checks in save-time methods; measure with ST05 (identical selects) and SAT, compare with implementation deactivated.

Practice this lesson

Quick check

1. A header-level check runs in PROCESS_ITEM of ME_PROCESS_PO_CUST. What is the main issue?

2. Which tool shows identical SELECT statements caused by a BAdI implementation?

3. Why should heavy SELECT logic be avoided inside BAdI methods?

Interview questions

1. A purchase order BAdI reads the vendor master for every item. What is the performance impact and how do you fix it?

Answer it in your own words first, then compare.

2. BAdI slows down document save by 200 ms. What do you do?

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