Optimized production order confirmation processing achieving 3x throughput improvement

Sharing our successful optimization of production order confirmation processing on SAP S/4HANA 1809. We manufacture automotive components across three plants with 150+ work centers processing 3,000-4,000 confirmations daily.

Original system performance was unacceptable - shop floor operators waited 15-25 seconds per confirmation on SAP Fiori apps. During shift changes, the system became nearly unusable with 40+ second response times. This impacted on-time delivery metrics and operator productivity significantly.

Our optimization project focused on SAP Fiori mobile performance, batch confirmation processing, parallel posting threads, CDS view optimization, and custom BADI implementation. Results: confirmation processing time reduced from 15-25 seconds to 4-6 seconds (3x improvement), shift-change bottlenecks eliminated, and on-time delivery improved by 12%.

The batch confirmation processing sounds interesting. How did you implement that without disrupting real-time visibility? Our management wants immediate confirmation data for production dashboards.

Let me provide comprehensive details on our implementation:

Project Context

  • Environment: SAP S/4HANA 1809, 3 manufacturing plants, 150+ work centers
  • Volume: 3,000-4,000 confirmations daily, peak 200-250 per hour during shift changes
  • Original Performance: 15-25 seconds per confirmation, 40+ seconds during peak
  • Target: Sub-5 second confirmation processing, eliminate shift-change bottlenecks
  • Business Impact: 12% improvement in on-time delivery, 30% increase in operator productivity

Optimization 1: SAP Fiori Mobile Optimization

Implemented multi-layer caching strategy:


// Pseudocode - Fiori app caching logic:
1. On app startup, cache master data locally:
   - Work centers (plant + work center list)
   - Material masters (only shop floor materials)
   - BOMs and routings (active versions only)
2. Set cache expiry: 2 hours for master data
3. For confirmations, query cache first:
   IF cache_valid AND data_exists THEN
     use_local_data
   ELSE
     fetch_from_backend AND update_cache
// Reduced backend calls from 12-15 per confirmation to 2-3

OData Service Optimization:

  • Reduced entity set projections to only required fields (was returning 50+ fields, now 12 fields)
  • Implemented server-side filtering instead of client-side
  • Added $expand only for necessary associations
  • Enabled batch requests for multiple confirmations

Offline Capability:

  • Operators can create confirmations without network connectivity
  • Confirmations stored locally, synced when connection restored
  • Conflict resolution: last-write-wins with manual review for exceptions

Result: Response time reduced from 15-25s to 6-8s (before other optimizations).

Optimization 2: Batch Confirmation Processing

Implemented staging table architecture:

Staging Table (ZCONF_STAGING):

  • Fields: confirmation_id, order_number, operation, quantity, timestamp, status
  • Confirmations write here immediately (sub-second operation)
  • Dashboard reads from staging table (real-time visibility maintained)

Batch Processing Job:


// Pseudocode - Batch processing logic:
1. Run every 5 minutes via scheduled job
2. SELECT confirmations WHERE status='PENDING'
3. Group by plant + work_center (avoid posting conflicts)
4. Create batches of 50-100 confirmations each
5. Submit to parallel posting threads
6. Update status='PROCESSING' during post
7. On success: status='POSTED', on error: status='ERROR'
// Average batch processing time: 45-60 seconds for 250 confirmations

Critical Operation Handling:

  • Final operation confirmations: post immediately (bypass batching)
  • Quality inspection confirmations: post immediately
  • Scrap/rework confirmations: post immediately
  • Regular operation confirmations: batched (95% of volume)

Result: Backend posting load reduced by 70%, eliminated shift-change performance degradation.

Optimization 3: Parallel Posting Threads

Configured parallel processing framework:

Thread Configuration:

  • 8 parallel posting threads (based on application server capacity)
  • Each thread processes one batch (50-100 confirmations)
  • Thread distribution: 3 threads for Plant 1, 3 for Plant 2, 2 for Plant 3
  • Lock management: group confirmations by order + operation to avoid conflicts

Conflict Prevention:

  • Confirmations for same production order grouped in single batch
  • Sequential processing within batch for same order
  • Parallel processing across different orders
  • Database locks managed at order level, not confirmation level

Implementation using custom function module:


FUNCTION z_parallel_conf_post
  IMPORTING batch_id TYPE z_batch_id
  EXPORTING return_status TYPE bapiret2
// Calls BAPI_PRODORDCONF_CREATE_TT in loop
// Commits after each 10 confirmations
// Error handling: log errors, continue processing

Result: Batch processing time reduced from 180s to 45-60s for 250 confirmations.

Optimization 4: CDS View Optimization

Optimized key production reporting views:

View 1: Work Center Capacity (Z_WC_CAPACITY_VIEW)

  • Original: Joined 5 tables (CRHD, CRCA, AFKO, AFPO, AUFK), 12-second query
  • Optimized: CDS view with associations, pre-calculated capacity, 800ms query
  • Used for: Real-time capacity dashboard on shop floor

View 2: Production Order Status (Z_PROD_ORD_STATUS)

  • Original: Complex joins across AUFK, AFKO, AFPO, AFVC, custom tables
  • Optimized: Hierarchical CDS view with @Analytics.dataCategory: #CUBE
  • Materialized key aggregations, updated every 15 minutes
  • Query time: 15s → 2s

View 3: Confirmation History (Z_CONF_HISTORY)

  • Combines posted confirmations (AFRU) + staging confirmations (ZCONF_STAGING)
  • Union view providing complete picture
  • Used by: Production dashboards, operator performance reports

CDS View Best Practices Applied:

  • Used associations instead of joins where possible
  • Pushed calculations to database layer using built-in functions
  • Implemented proper WHERE conditions at view level
  • Added appropriate indexes on underlying tables

Result: Dashboard refresh time reduced from 20-30s to 3-5s.

Optimization 5: Custom BADI Implementation

Implemented BADI for confirmation validation and enrichment:

BADI: WORKORDER_CONFIRM (Enhancement Spot: SHOPFLOOR_CONTROL)

Purpose: Pre-validate confirmations before posting, enrich with additional data


// Pseudocode - BADI implementation:
METHOD if_badi_workorder_confirm~validate.
  // 1. Validate operator authorization
  IF NOT is_authorized(operator_id, work_center) THEN
    add_error('Operator not authorized')
    RETURN
  // 2. Check material availability
  IF yield_qty > available_qty THEN
    add_warning('Insufficient material')
  // 3. Enrich with quality data
  READ quality_results WHERE order=confirmation-order
  confirmation-quality_status = quality_results-status
  // 4. Calculate actual duration vs. standard
  confirmation-efficiency = standard_time / actual_time
ENDMETHOD

BADI Benefits:

  • Centralized validation logic (no custom code in Fiori apps)
  • Consistent business rules across confirmation channels
  • Performance: validation runs in staging write (sub-second), not during posting
  • Enrichment data available immediately in dashboards

Result: Reduced posting errors by 60%, improved data quality.

Implementation Timeline

Phase 1 (Weeks 1-3): Fiori Optimization

  • Implemented caching framework
  • Optimized OData services
  • Deployed offline capability
  • Result: 40% improvement (15-25s → 9-15s)

Phase 2 (Weeks 4-6): Batch Processing

  • Built staging table architecture
  • Developed batch processing job
  • Configured critical operation bypass
  • Result: Additional 30% improvement (9-15s → 6-10s)

Phase 3 (Weeks 7-9): Parallel Posting & CDS Views

  • Configured parallel threads
  • Optimized key CDS views
  • Rebuilt production dashboards
  • Result: Additional 40% improvement (6-10s → 4-6s)

Phase 4 (Weeks 10-12): BADI & Fine-tuning

  • Implemented custom BADI
  • Performance tuning and monitoring
  • User training and rollout
  • Result: Final optimization, stable 4-6s performance

Key Metrics Achieved

Performance Metrics:

  • Confirmation response time: 15-25s → 4-6s (3x improvement)
  • Shift-change peak performance: 40s → 8s (5x improvement)
  • Dashboard refresh time: 20-30s → 3-5s (5-6x improvement)
  • Batch processing throughput: 60 conf/hour → 250 conf/hour (4x improvement)

Business Metrics:

  • On-time delivery: 78% → 90% (+12 points)
  • Operator productivity: 85 conf/operator/shift → 110 conf/operator/shift (+30%)
  • Confirmation errors: 5% → 2% (-60%)
  • System availability during peak: 85% → 99% (+14 points)

Lessons Learned

  1. Fiori caching is critical for mobile shop floor apps - master data rarely changes
  2. Batch processing doesn’t mean sacrificing visibility - staging tables provide real-time view
  3. Parallel posting requires careful conflict management - group by logical units
  4. CDS views should be designed with dashboard requirements in mind from start
  5. BADIs centralize logic - avoid custom code scattered across apps
  6. Incremental rollout allowed us to validate each optimization before proceeding
  7. Operator training was as important as technical implementation

Technical Architecture Summary

Front-end: SAP Fiori (cached master data, offline-capable)

OData Services (optimized projections, batch requests)

Staging Layer (ZCONF_STAGING table, immediate write)

Batch Processing (5-min intervals, 8 parallel threads)

BADI Validation (pre-post enrichment and validation)

SAP Standard Posting (BAPI_PRODORDCONF_CREATE_TT)

CDS Views (optimized reporting, real-time dashboards)

This architecture provides the best of both worlds: responsive user experience with efficient backend processing. The key is decoupling user interaction from backend posting through the staging layer.