Best Practices for Retry Mechanisms and Error Handling for External API Failures in Mendix

0
Hi Everyone,I am working on integrating external REST APIs with a Mendix application and would like to understand the approaches used in production environments.When an external API becomes unavailable due to network issues, timeouts, rate limiting, or temporary server errors, what is the recommended way to handle these failures in Mendix?Some specific areas I am interested in:Do you implement automatic retries, and if so, how many retry attempts are considered reasonable?Do you use Task Queues, Scheduled Events, or custom retry mechanisms for asynchronous processing?How do you log and monitor failed API requests for troubleshooting?What strategies do you use to prevent duplicate transactions when a retry occurs?Are there any common patterns or Marketplace modules that help with resilient API integrations?I would appreciate hearing about real-world experiences and best practices from enterprise Mendix projects.Thank you in advance for your insights.
asked
2 answers
1

In enterprise projects, I generally avoid implementing retries directly in the user request, as it can increase response times and create a poor user experience.


My usual approach is:

  • Retry only for transient errors such as timeouts, HTTP 429 (rate limiting), and 5xx server errors. I typically use 3 retry attempts with exponential backoff.
  • For long-running or non-blocking integrations, I use Task Queues so the API call is processed asynchronously. If all retries fail, the request is moved to a retry/error queue for later processing.
  • Maintain an API Log entity that stores the request, response, status code, retry count, timestamp, and error message. This makes troubleshooting much easier.
  • To avoid duplicate transactions, use an idempotency key or a unique business identifier so repeated requests don't create duplicate records.
  • For monitoring, integrate with tools such as Application Insights, Elastic, or your organization's logging platform, and configure alerts for repeated failures.


The most important thing is to separate the API handling into a dedicated integration layer instead of calling external APIs directly from business microflows. This makes retries, logging, monitoring, and future maintenance much easier.


Kindly mark this as the accepted answer if it helps.

answered
0

Hi Serina Delveen


what you asked is a full end to end implemetation lets divide it into 3 different section so it will be easy to understand, as per your 1st question


Retry Strategy


1.Use 3 retry attempts as the standard not too aggressive, not too passive. Lets say if it holds transactional data like payment ects, It is always better to combine taskqueue and schedulers bez due to 500 series error the system's particular server or node might be failed but the task action might be taken in that case your taskqueue will fail for sure so once the 3 time retry failed mark the status as failed due to server un reach or anything. later use a scheduler to pick those failed task and try again.[ Note: if you are using this make sure that the status is updated properly].


2.Always setup retry at +15s, +30s, +90s intervals and Only retry on transient errors HTTP 429, 500, 502, 503, 504, and timeouts.


3.Never retry on 400, 401, 403, 404 these are permanent failures, retrying wastes cycles.


Async Processing


  1. Use Task Queue for fire-and-forget outbound API calls in Mendix 9+.
  2. Use Scheduled Events for batch/bulk API processing with a queue table.
  3. For critical transactional calls, keep them synchronous with inline retry logic.
  4. Create an APIOutboxQueue entity to persist retry state across runtime restarts.
  5. Queue entity should store — Endpoint, Payload, Status, RetryCount, NextRetryAt, LastError, CorrelationID.
  6. Status enum should cover — Pending, Processing, Success, Failed, DeadLetter.
  7. Scheduled Event polls every 1–2 minutes for records where Status = Pending AND NextRetryAt <= Now.


Logging & Monitoring


  1. Always generate a CorrelationID (UUID) at the start of every API transaction.
  2. Log — CorrelationID, Endpoint, HTTP Method, Status Code, Response Time, Retry Attempt, Error Message, Timestamp.
  3. Use a dedicated log node (e.g., RestIntegration) to separate API logs from app logs.
  4. Log INFO for success, WARNING for retry triggered, ERROR for max retries exhausted.
  5. On EKS, pipe logs to CloudWatch and set alarms on ERROR log node spikes.
  6. Monitor queue depth — alert ops when DeadLetter count starts growing.


Preventing Duplicate Transactions


  1. Generate a UUID Idempotency Key before the first attempt and send it as a request header (X-Idempotency-Key).
  2. Before processing a queued record, set Status = Processing in a committed transaction first — prevents two workers picking the same record.
  3. Store the external system's returned reference/transaction ID after a successful call.
  4. On retry response, check if that reference ID already exists before creating new records in your domain model.


Circuit Breaker Pattern


  1. Track API health in a CircuitBreakerState entity — State (Closed / Open / HalfOpen), FailureCount, OpenedAt.
  2. Closed = normal operation, calls go through.
  3. Open = failure threshold crossed (e.g., 5 failures in 2 min) — skip calls immediately, return fallback.
  4. Half-Open = after cooldown (e.g., 60s), send one probe call — success reopens circuit, failure keeps it open.
  5. This prevents your runtime thread pool from being exhausted on a completely dead endpoint.


I hope this helps all your question, Need more help in designing this let me know , I can help



answered