---
title: DNS
description: Use Bun's DNS module to resolve DNS records
---

Bun implements its own `dns` module and the `node:dns` module.

```ts
import * as dns from "node:dns";

const addrs = await dns.promises.resolve4("bun.com", { ttl: true });
console.log(addrs);
// => [{ address: "172.67.161.226", ttl: 0 }, ...]
```

```ts
import { dns } from "bun";

dns.prefetch("bun.com", 443);
```

---

## DNS caching in Bun

Bun caches DNS lookups, which makes repeated connections to the same hosts faster.

The cache holds up to 256 entries for a maximum of 30 seconds each. If a connection to a host fails, Bun removes that host's entry from the cache. Simultaneous connections to the same host share one DNS lookup.

This cache is automatically used by:

- `bun install`
- `fetch()`
- `node:http` (client)
- `Bun.connect`
- `node:net`
- `node:tls`

### When should I prefetch a DNS entry?

Web browsers expose [`<link rel="dns-prefetch">`](https://developer.mozilla.org/en-US/docs/Web/Performance/dns-prefetch) to resolve a hostname before it's needed. In Bun, `dns.prefetch` does the same thing: use it when you know you'll connect to a host soon and want to avoid the initial DNS lookup.

```ts
import { dns } from "bun";

dns.prefetch("my.database-host.com", 5432);
```

A database driver is a good example: prefetch the database host's DNS entry when your application starts, and by the time the rest of the application has loaded, the lookup may already be complete.

### `dns.prefetch`

<Warning>This API is experimental and may change in the future.</Warning>

`dns.prefetch` resolves a hostname before you need it.

```ts
dns.prefetch(hostname: string, port?: number): void;
```

Here's an example:

```ts
import { dns } from "bun";

dns.prefetch("bun.com", 443);
//
// ... sometime later ...
await fetch("https://bun.com");
```

### `dns.getCacheStats()`

<Warning>This API is experimental and may change in the future.</Warning>

`dns.getCacheStats()` returns the current cache stats as an object with the following properties:

```ts
{
  cacheHitsCompleted: number; // Cache hits completed
  cacheHitsInflight: number; // Cache hits in flight
  cacheMisses: number; // Cache misses
  size: number; // Number of items in the DNS cache
  errors: number; // Number of times a connection failed
  totalCount: number; // Number of times a connection was requested at all (including cache hits and misses)
}
```

Example:

```ts
import { dns } from "bun";

const stats = dns.getCacheStats();
console.log(stats);
// => { cacheHitsCompleted: 0, cacheHitsInflight: 0, cacheMisses: 0, size: 0, errors: 0, totalCount: 0 }
```

### Configuring DNS cache TTL

Bun caches DNS entries for 30 seconds by default. To change the TTL, set the `$BUN_CONFIG_DNS_TIME_TO_LIVE_SECONDS` environment variable. For example, to set it to 5 seconds:

```sh
BUN_CONFIG_DNS_TIME_TO_LIVE_SECONDS=5 bun run my-script.ts
```

#### Why is 30 seconds the default?

The system API underneath (`getaddrinfo`) does not expose the TTL of a DNS entry, so Bun has to pick a number. We chose 30 seconds because it's long enough to see the benefits of caching and short enough to be unlikely to cause issues if a DNS entry changes. [Amazon Web Services recommends 5 seconds](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/jvm-ttl-dns.html) for the Java Virtual Machine, though the JVM's default is to cache indefinitely.
