Travel expense sync timing out when integrating third-party booking system

We’re experiencing consistent timeout failures when syncing travel expense data from our third-party booking platform to Workday. The integration runs every 2 hours via REST API and processes employee travel bookings for expense reimbursement.

The sync works fine for small batches (under 50 records) but consistently fails with 504 Gateway Timeout errors when processing 100+ records. Our current API timeout is set to 60 seconds, and we’re sending the entire payload in a single POST request.


POST /ccx/service/workday/Travel_Expense_Import/v1
Timeout: 60000ms
Payload: 150 expense records (avg 2KB each)
Error: HTTP 504 Gateway Timeout

The batch processing happens synchronously, and we’re noticing the timeout occurs around the 58-second mark consistently. We’ve tried increasing the timeout to 90 seconds, but that just delays the inevitable failure on larger batches. The asynchronous integration patterns aren’t currently implemented, and our payload optimization is minimal - we’re sending full expense detail objects rather than summary data.

This is blocking our month-end expense reconciliation process. Has anyone dealt with similar API timeout issues when integrating travel expense data at scale?

Let me provide a comprehensive solution that addresses all the key areas you need to tackle:

1. API Timeout Configuration: Set your client-side timeout to 90 seconds minimum, but understand this is just a safety net. The real fix is reducing the work per API call. Configure connection pooling with max 10 concurrent connections to Workday to prevent overwhelming their infrastructure.

2. Batch Processing Strategy: Implement chunking with 25 records per batch as your starting point. Here’s the approach:


// Batch submission logic
BatchSize = 25 records
DelayBetweenBatches = 8 seconds
For each chunk: Submit -> Log batch ID -> Continue

This keeps each API call under 20 seconds and respects rate limits. Track each batch submission in a control table with status (SUBMITTED, PROCESSING, COMPLETED, FAILED).

3. Asynchronous Integration Pattern: Shift to a submit-and-poll model. After submitting each batch, store the Workday batch ID and implement a separate polling process:

  • Poll every 45 seconds for status updates
  • Max 10 poll attempts before marking as stuck
  • Use Workday’s Get_Integration_Events API to check batch completion
  • This decouples submission from completion and prevents timeout errors

4. Payload Optimization: This is critical - reduce your 2KB per record to under 800 bytes:

  • Send expense category IDs instead of full category objects (saves ~400 bytes)
  • Reference approval chain by worker ID only, not full hierarchy (saves ~600 bytes)
  • Omit optional fields that can be derived or defaulted in Workday
  • Use compressed JSON if your middleware supports it

Example optimized payload structure:


{
  "expense_id": "EXP-2025-0001",
  "worker_ref": "WID-123",
  "amount": 245.50,
  "category_id": "CAT-TRV-001",
  "date": "2025-03-15"
}

Implementation Steps:

  1. Build the chunking logic in your integration layer first - this gives immediate relief
  2. Optimize payloads to reduce processing time per record - aim for 40% size reduction
  3. Implement async polling mechanism - this prevents future scaling issues
  4. Add retry logic with exponential backoff (retry after 2min, 5min, 10min)
  5. Set up monitoring alerts for batch failures and processing time trends

Expected Results: With these changes, your 150-record sync should complete in 90-120 seconds total (6 batches × 15 seconds processing time + polling overhead) versus timing out at 60 seconds. You’ll also be able to scale to 500+ records without architectural changes.

The async pattern is the most important change - it transforms this from a blocking operation that fails under load to a resilient queue-based system that handles volume gracefully.


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

I’ve seen this pattern before with Workday Web Services. The 60-second timeout you’re hitting is likely a combination of Workday’s processing time and network latency. When you’re sending 150 records at 2KB each, that’s 300KB of data that needs to be validated, transformed, and committed in a single transaction.

The issue isn’t just the timeout value - it’s that you’re using synchronous processing for what should be an asynchronous workflow. Even if you increase the timeout to 120 seconds, you’ll eventually hit the same wall as your data volume grows. Have you considered implementing a chunking strategy where you split the 150 records into batches of 25-30?

The synchronous approach is definitely your bottleneck. I’d recommend moving to an asynchronous integration pattern using Workday’s Document Delivery Service or implementing a queuing mechanism on your side. This way, you submit the batch and poll for completion status rather than waiting for the entire process to complete in one API call.

Also, look at your payload optimization - do you really need to send all 2KB per record? In most travel expense integrations, you can reduce this to 500-800 bytes by sending only required fields and using reference IDs instead of full object hierarchies. This alone could cut your processing time in half.

Thanks for the suggestions. We haven’t implemented any chunking yet - currently it’s all-or-nothing on the batch. The 2KB per record includes nested objects for expense categories, tax details, and approval chains. I can see how that’s excessive.

What size chunks would you recommend for travel expense data? And for the asynchronous pattern, would we need to set up a separate monitoring process to track completion status?

Tested this on our Concur-to-Workday integration and dropping to 25-record batches with 8-second delays eliminated the timeout errors we’d seen for months.

For chunk sizing, I typically go with 20-30 records per batch for expense data, but it depends on your record complexity. Start conservative at 20 and tune upward based on actual performance metrics. You want each batch to complete well under 30 seconds to leave room for network variance and Workday processing spikes during peak hours.

Regarding monitoring, yes - you’ll need a status tracking mechanism. Most implementations use a simple database table to track batch submission status, then have a separate polling job that checks completion every 30-60 seconds. The overhead is worth it for reliability at scale.

One thing I haven’t seen mentioned yet is the API timeout configuration on both ends. Workday has server-side timeout limits that you can’t control, but you should verify your client-side timeout settings aren’t causing premature disconnections. I’ve seen cases where the client timeout was set to 60 seconds while Workday was still processing and would have completed at 65 seconds.

Also check if you’re implementing proper retry logic with exponential backoff. Sometimes a 504 is transient due to Workday infrastructure load, and a retry 2-3 minutes later succeeds without any code changes.

I’d add one more consideration about the batch processing strategy - make sure you’re not hitting Workday’s rate limiting thresholds. If you chunk into 20-record batches and fire them all simultaneously, you might trigger rate limiting which manifests as timeouts or 429 errors. Stagger your batch submissions by 5-10 seconds to stay within API quotas.