Skip to content

Implement DNS querying cache management API #57641

Closed as not planned
Closed as not planned

Description

@Ethan-Arrowood

What is the problem this feature will solve?

Follow up to #57640 , we should create an API that allows users to specify the DNS querying cache TTL.

With the addition of this API, we should restore the default behavior to match the (sensible) defaults of c-ares (i.e. remove the qcache_max_ttl=0`).

I will contribute this in the coming days.

What is the feature you are proposing to solve the problem?

API I have in my head is to add a ttl option to https://nodejs.org/api/dns.html#resolveroptions and to all of the shortcuts too i.e. https://nodejs.org/api/dns.html#dnsresolvehostname-rrtype-callback

Something like dns.resolve('...', { ttl: 100 }, () => {}); or new dns.Resolver({ ttl: 100 });

What alternatives have you considered?

No response

Activity

  1. added
    dnsIssues and PRs related to the dns subsystem.
    caresIssues and PRs related to the c-ares dependency or the cares_wrap binding.
    on Mar 26, 2025
  2. ronag commented on Mar 28, 2025

    @ronag
    Member

    Should we somehow automatically clear the cache if we detect a connection error to a cached IP? Does that make sense?

  3. Ethan-Arrowood commented on Apr 14, 2025

    @Ethan-Arrowood
    ContributorAuthor

    I noticed that the shorthands already have a ttl option: https://nodejs.org/api/dns.html#dnsresolve4hostname-options-callback

    So this is a little confusing. Should I call the new thing maxTTL or something else?

  4. Ethan-Arrowood commented on Apr 14, 2025

    @Ethan-Arrowood
    ContributorAuthor

    @ronag I'm trying to demonstrate the cache timings, but with or without the fix in #57640 I'm seeing DNS caching. I believe this is my system level cache and not the one in Node?

    Do you have or anyone in @nodejs/dns know how I can reliably test the c-ares cache only?

    This is the naive script I'm using:

    import { PerformanceObserver } from 'node:perf_hooks';
    import { resolve4 } from 'node:dns/promises';
    import { setTimeout } from 'node:timers/promises';
    
    let c = 1;
    const obs = new PerformanceObserver((items) => {
    	items.getEntries().forEach((item) => {
    		console.log(`DNS query ${c++} took ${item.duration}ms`);
    	});
    });
    obs.observe({ entryTypes: ['dns'] });
    
    console.log('Cache Test of github.com');
    
    await resolve4('github.com', { ttl: true })
    let result = await resolve4('github.com', { ttl: true });
    
    // Sleep for TTL of dns query 2
    await setTimeout((result[0].ttl + 1) * 1000);
    
    await resolve4('github.com', { ttl: true });
    await resolve4('github.com', { ttl: true });
    

    I've ran this with a local build of main branch (which contains the qcache_max_ttl=0 fix), but I'm still observing caching happening.

    Cache Test of github.com
    DNS query 1 took 6.98ms
    DNS query 2 took 0.1665840000000003ms
    DNS query 3 took 49.486541999998735ms
    DNS query 4 took 1.5781669999996666ms
    

    Which query caching disabled, I'd expect for each query to take about the same amount of time. But as my script demonstrates, only if you wait for the returned ttl to expire will it be a new hit.

  5. metcoder95 commented on Apr 21, 2025

    @metcoder95
    Member

    Might be that you are hitting the system level caching; depending what OS you use you might/might-not be able to disable it completely.

    For Mac, it is a service that keeps the records in memory. So you might need to kill such service upon request (I guess, not sure if it will work correctly), but c-ares cache should be bypassed with the PR you shared (AFAICT)

  6. Ethan-Arrowood commented on Apr 23, 2025

    @Ethan-Arrowood
    ContributorAuthor

    Okay, but how could I add a unit test to Node for this?

  7. ronag commented on Apr 24, 2025

    @ronag
    Member

    I see the same on linux + 22.15.0... which is concerning...

  8. Ethan-Arrowood commented on Apr 24, 2025

    @Ethan-Arrowood
    ContributorAuthor

    I spent some time trying to go around my system cache, but I couldn't get anything to show different results.

    Based on the c-ares docs I do agree the fix was appropriate and correct, I just cannot test it in anyway 😅

  9. augjoh commented on May 17, 2025

    @augjoh

    @Ethan-Arrowood, @ronag : The flag ARES_OPT_QUERY_CACHE is missing in ares_init_options(3) call and the fix in #57640 is incomplete. Perhaps this should be added as well.

  10. Ethan-Arrowood commented on May 18, 2025

    @Ethan-Arrowood
    ContributorAuthor

    Oh I see now - okay I will add that and try my tests again to see if maybe that enables me to test it

  11. Ethan-Arrowood commented on May 20, 2025

    @Ethan-Arrowood
    ContributorAuthor

    Please review: #58404

    I'm still unable to test this locally. @ronag since it seems like you have a system that allows you to disable the system dns cache can you try?

    Would it be appropriate for me to write a test that only runs on a certain Linux subsystem?

    I've pushed my implementation for making this value configurable here: Ethan-Arrowood@324cb36 if you want to take a look at what I've come up with so far.

  12. ronag commented on May 20, 2025

    @ronag
    Member

    Sorry. No bandwidth.

  13. Ethan-Arrowood commented on Jun 3, 2025

    @Ethan-Arrowood
    ContributorAuthor

    The additional fix has been merged.

    Still open to ideas for how to improve testing of this feature. I think assertions would be necessary before we could add a new feature that enables it to be configurable.

  14. MomenNano commented on Sep 11, 2025

    @MomenNano

    Can we align Node’s DNS query cache behavior with c-ares by using a 1-hour TTL by default.

    Rollout options:

    Option A (preferred, if timing allows): Make 1-hour the default cache TTL in v25 as a semver-major change.
    Option B:
    In v25 (as a semver-minor) add an option to set the DNS cache TTL (e.g., via Resolver options), defaulting to “no cache change.”
    then in v26 (as a semver-major) switch the default to a 1-hour TTL.

    This keeps us consistent with c-ares’ sensible defaults while giving users an opt-in path before the default changes. If there are concerns about backward compatibility (e.g., environments that depend on immediate DNS changes), we can document clear opt-out/override mechanisms and consider an environment variable for global control.

    This would help the performance if no caching is implemented at the platform/infra level

    Cc @Ethan-Arrowood @mcollina

  15. github-actions commented on Mar 11, 2026

    @github-actions
    Contributor

    There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the never-stale Issues and PRs exempt from automated stale handling. label or close this issue if it should be closed. If not, the issue will be automatically closed 6 months after the last non-automated comment.
    For more information on how the project manages feature requests, please consult the feature request management document.

  16. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Mar 11, 2026
  17. metcoder95 commented on Mar 20, 2026

    @metcoder95
    Member

    What's the overall plan on this; happy to support ongoing efforts on this one

  18. removed
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Mar 21, 2026
  19. khalidsaidi commented on Mar 25, 2026

    @khalidsaidi
  20. github-actions commented on Jul 20, 2026

    @github-actions
    Contributor

    This issue has been marked as stale due to 90 days of inactivity.
    It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

  21. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jul 20, 2026
  22. github-actions commented on Aug 20, 2026

    @github-actions
    Contributor

    This issue has been automatically closed after 30 days of inactivity following its stale status (no activity for a total of 120 days).
    If this is still relevant, feel free to reopen it or leave a comment with additional details so we can continue the discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

caresIssues and PRs related to the c-ares dependency or the cares_wrap binding.dnsIssues and PRs related to the dns subsystem.feature requestIssues requesting new Node.js features.staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions