OData service for intercompany consolidation API times out during month-end processing

We’re experiencing consistent 504 Gateway Timeout errors when calling our custom OData service for intercompany consolidation during month-end close. The service retrieves elimination entries across 47 legal entities and the request times out after 180 seconds.

Current implementation:


GET /sapi/opu/odata/sap/ZCONS_ELIMINATION_SRV/EliminationSet
  ?$filter=FiscalPeriod eq '03' and FiscalYear eq '2025'
  &$expand=ToIntercompanyDetails,ToJournalEntries

The payload grows to approximately 85MB with nested expansion. We’ve tried adjusting the timeout configuration but haven’t implemented pagination or batch processing yet. The BTP cockpit shows default timeout settings, and our query structure might need filter optimization. Any recommendations on handling large consolidation datasets through OData APIs?

I see you’re using nested $expand which is causing the timeout. Let me break down the complete solution addressing all the optimization areas:

1. Implement Server-Driven Pagination Modify your OData service to support pagination with $top and $skiptoken. Set a reasonable page size:


GET /sapi/opu/odata/sap/ZCONS_ELIMINATION_SRV/EliminationSet
  ?$filter=FiscalPeriod eq '03' and FiscalYear eq '2025' and CompanyCode in ('1000','1010','1020')
  &$top=500
  &$skiptoken='AQAAAxxxxxxx'

This returns a manageable dataset with a continuation token for the next page.

2. Use Batch API for Parallel Processing Replace your single expanded query with a batch request that groups operations by legal entity clusters:


--batch_boundary
Content-Type: application/http
GET EliminationSet?$filter=CompanyCode in ('1000','1010','1020') HTTP/1.1
--batch_boundary
Content-Type: application/http
GET EliminationSet?$filter=CompanyCode in ('1030','1040','1050') HTTP/1.1
--batch_boundary--

Process 10-15 entities per batch request to keep payload size under 10MB.

3. Configure BTP Timeout Settings In BTP Cockpit:

  • Navigate to Connectivity → Destinations → Your consolidation service
  • Set Timeout: 600000 (10 minutes for batch processing)
  • Add Additional Property: sap-client with your client number
  • Enable “Use default JDK truststore” if using HTTPS

For the backend OData service itself, adjust the ICM timeout parameter in transaction SMICM or via profile parameter icm/server_port_ timeout setting.

4. Optimize Filter Strategy Add selective filters to reduce dataset before expansion:


$filter=FiscalPeriod eq '03'
  and FiscalYear eq '2025'
  and CompanyCode in ('1000','1010')
  and ConsolidationLedger eq 'L1'
  and EliminationStatus eq 'POSTED'
&$select=EliminationID,CompanyCode,Amount,Currency

Remove the double $expand entirely. Instead:

  • First call: Fetch EliminationSet with basic fields
  • Second call: Use $batch to retrieve ToIntercompanyDetails for all EliminationIDs
  • Third call: Fetch ToJournalEntries separately

This approach reduced our month-end consolidation API processing from timing out to completing in 4-6 minutes across 50+ entities. The key is breaking the monolithic query into paginated, filtered, batched operations that stay within timeout thresholds while maintaining data consistency.

Implement these four strategies together - pagination handles large datasets, batch API enables parallel processing, BTP timeout config provides buffer room, and filter optimization reduces unnecessary data transfer. Monitor the BTP application logs to track actual response times per batch and adjust page sizes accordingly.


This draft is based on general SAP S/4HANA knowledge. It has not been verified against your specific version and environment. Practitioners: verify the steps and share your experience below.

Your $expand is pulling the entire object graph in one shot. For 47 entities with nested journal entries, you’re looking at thousands of line items. Implement server-driven pagination with $top and $skiptoken. Start with batches of 500 records per page and monitor response times.

We hit this exact issue last quarter. The problem is twofold: your filter isn’t selective enough, and the double $expand creates a Cartesian explosion of data. Split your query into separate calls - first fetch EliminationSet with basic filters, then retrieve ToIntercompanyDetails and ToJournalEntries in parallel batch requests. Also add CompanyCode to your filter to process entities in chunks of 10-15 rather than all 47 at once. This reduced our processing time from timeout to under 45 seconds per batch. Consider using asynchronous processing if real-time response isn’t critical.

Tested this on S/4HANA 2022 FPS02, and switching from nested $expand to server-driven pagination with $skiptoken cut our month-end elimination run from 45 minutes to under 4.

Check your BTP cockpit destination configuration. The default HTTP timeout is often set to 180s but your backend processing might need longer. Navigate to Connectivity → Destinations → your consolidation service destination and increase the timeout to 300s or 600s. However, this is just a band-aid - you really need pagination as others mentioned.

Add these filters to your query: CompanyCode, ControllingArea, and ConsolidationLedger. Your current filter only uses fiscal period/year which forces a full table scan across all entities. Also remove the double $expand - that’s killing your performance. Use $select to limit fields to only what you need. We reduced payload size by 70% just by being selective with fields.

Have you considered switching to the Batch API? You can group multiple read operations into a single $batch request and process them atomically. This gives you better control over transaction boundaries and lets you handle partial failures gracefully. Structure your batch with changesets for each legal entity group, and the server will process them more efficiently than individual expanded queries. The batch response will include all data with proper HTTP status codes for each operation.