---
title: 'Undici Issues on Appwrite'
excerpt: "Function timeouts with Node 20+ on Appwrite - here's how I fixed it."
date: 2024-06-29
categories: appwrite, web
featureImage: '/images/appwrite.webp'

prev:
  text: 'AppExpress Essentials'
  link: '/blog/appexpress-essentials'

next:
  text: 'Chrome Shortcuts'
  link: '/blog/chrome-shortcuts'
---

Recently, I migrated one of my iOS Apps from a basic PHP server to Appwrite, and overall, the transition was smooth.
While I did encounter some minor hiccups with data migration, they were manageable.

However, one particular challenge arose when working with Functions, especially using the `Node:20+` Runtime. Consider
this snippet of code -

```js
// exactly 60 items in here.
for (const [index, randomId] of randomIds.entries()) {
    try {
        const document = await databases.getDocument(
          databaseId,
          collectionId,
          randomId.toString(),
        );

        // perform updates on the document.
        await updateDocument(document, index);
    } catch (error) {
        console.error(`Index: ${index + 1}, Identifier: ${randomId}, ${error}`);
    }
}
```

<Badge type="info">If you're wondering why I'm not using something like Promise.all, we'll address that shortly.</Badge>

In a `Node:20+` runtime environment, I often encountered this error:

```json
{
  "error": {
    "cause": {
      "code": "ETIMEDOUT"
    }
  }
}
```

Upon investigating, I learned about recent changes to `undici`, which handles native `fetch` operations in Node.js,
particularly related to DNS resolution when connecting to domains. While this seemed like a DNS issue, I also considered
my Cloudflare setup because I was using an additional domain via `CNAME` in my Appwrite Project.

Here are the specific test results with `Node:20`:

1. Main Domain => **Pass** ✅
2. CNAME Domain With Cloudflare Proxy **On** => **Fail** ❌
3. CNAME Domain With Cloudflare Proxy **Off** => **Pass** ✅

The solution was either to stick with the main domain assigned to the Appwrite instance or revert to using a Node
Runtime version less than 20. Using main domain after assigning a relevant domain wasn't something I wanted, so I
just bumped back to using `Node:18` & that seems to fix the issue.

---
Regarding the comment on `Promise.all`, while it's faster, the timeout issues made it impossible to process updates or
fetch documents due to concurrent timeouts. The current logic with the `for` loop worked, although I had to use `delay`
to avoid the timeouts. However, this approach wasn't effective, and it also significantly increased the processing time
for such a small number of documents.

---
The issue can be tracked here: [Appwrite GitHub Issue #8311](https://github.com/appwrite/appwrite/issues/8311).