{"id":1624,"date":"2026-11-06T22:23:47","date_gmt":"2026-11-06T22:23:47","guid":{"rendered":"https:\/\/virtualserversvps.com\/blog\/?p=1624"},"modified":"2026-11-06T22:23:47","modified_gmt":"2026-11-06T22:23:47","slug":"vps-sssd-nss-caching-ldap-lookup-latency","status":"publish","type":"post","link":"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/","title":{"rendered":"NSS and SSSD Caching on a VPS: Killing LDAP Lookup Stalls"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><code>time getent passwd deploy<\/code> returning in 40 ms looks harmless until you multiply it by a hundred thousand per hour. On a VPS that authenticates against LDAP or Active Directory, every <code>getpwnam()<\/code>, <code>getgrnam()<\/code> and group membership check can become a network round trip. The classic pathology is a web request that feels 300 ms slower than it should, because nginx or a PHP-FPM worker triggered an NSS lookup for a supplementary group over the network. The fix is almost always caching, and on modern systems that means <code>nsswitch.conf<\/code> with <code>sss<\/code> in front and SSSD&#8217;s <code>memcache_timeout<\/code> and enumeration controls tuned.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This article walks through measuring the lookup cost, configuring SSSD so that a normal lookup never blocks on the network, and verifying the cache is actually being hit. It assumes Rocky, Alma, Ubuntu or Debian with SSSD installed and <code>realmd<\/code> or a hand-written <code>sssd.conf<\/code> binding to an LDAP directory.<\/p>\n\n\n<!-- wp:heading level=\"2\" -->\n<h2>Measuring the Baseline Lookup Cost<\/h2>\n<!-- \/wp:post-content -->\n\n<!-- wp:paragraph -->\n<p>Start with the tool the C library actually uses. <code>getent<\/code> resolves through every NSS module in order, so its runtime is the true user-visible cost. Run it repeatedly with the cache cold and warm, and compare with a direct network query.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>for i in $(seq 1 5); do\n  \/usr\/bin\/time -f '%e s' getent passwd deploy 2&gt;&amp;1 | tail -1\ndone\nfor i in $(seq 1 5); do\n  \/usr\/bin\/time -f '%e s' getent group wheel 2&gt;&amp;1 | tail -1\ndone\n# direct LDAP round trip for comparison\nldapsearch -H ldaps:\/\/dc1.example.com -x -b 'dc=example,dc=com' \\\n  '(uid=deploy)' uid 2&gt;\/dev\/null | grep -c '^uid:'<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:paragraph -->\n<p>If <code>getent<\/code> is steadily 20\u201360 ms and <code>ldapsearch<\/code> shows the same, you are paying a full network round trip per lookup. Worse, if the first <code>getent<\/code> takes 5\u201312 seconds, you are hitting a resolver timeout or an unreachable server being retried. Both are SSSD configuration problems rather than application bugs.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Confirm which module answers the query with <code>getent -s sss passwd deploy<\/code> versus <code>getent -s files passwd root<\/code>. If the first is slow and the second instant, the cost is entirely in the directory path and caching is the lever.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading level=\"2\" -->\n<h2>Ordering nsswitch Correctly<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Order matters because NSS stops at the first module that returns a hit. <code>files<\/code> first is mandatory for local service accounts; <code>sss<\/code> should follow and <code>ldap<\/code> should generally be absent if SSSD is managing the connection, because a direct <code>ldap<\/code> module bypasses the cache entirely.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code># \/etc\/nsswitch.conf\npasswd:     files sss systemd\ngroup:      files sss systemd\nshadow:     files sss\nhosts:      files dns myhostname\nsudoers:    files sss\nservices:   files sss<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:paragraph -->\n<p>Removing <code>ldap<\/code> from <code>passwd<\/code> and <code>group<\/code> is a common rescue for slow logins. The direct module has no negative cache, so a miss for a non-existent user retries the server each time. SSSD, by contrast, records negative results and answers from the cache. Run <code>getent passwd<\/code> after the change and compare time-to-first-line; a large drop usually means the direct module was taking hits.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading level=\"2\" -->\n<h2>SSSD Cache Priming and Timers<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>SSSD&#8217;s NSS responder serves from a local LDB database, refreshed in the background. Three options matter: <code>memcache_timeout<\/code> controls in-memory caching of results, <code>entry_cache_timeout<\/code> controls how long a user record is trusted on disk, and <code>refresh_expired_interval<\/code> controls proactive refresh.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code># \/etc\/sssd\/sssd.conf\n[domain\/example.com]\nid_provider = ldap\nauth_provider = ldap\nldap_uri = ldaps:\/\/dc1.example.com\ncache_credentials = true\nentry_cache_user_timeout = 3600\nentry_cache_group_timeout = 3600\nentry_cache_netgroup_timeout = 3600\nrefresh_expired_interval = 300\n\n[nss]\nmemcache_timeout = 600\nenumerate = false\nfilter_users = root, nobody\nfilter_groups = root, nobody<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:paragraph -->\n<p><code>enumerate = false<\/code> is critical on a VPS. When enabled, SSSD lists every user and group in the directory at startup and periodically, which turns a small directory into a sustained CPU and network load and makes <code>getent passwd<\/code> with no argument crawl. Most applications never need it. <code>filter_users<\/code> prevents lookups for local accounts from ever reaching the directory.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>A one-hour <code>entry_cache_user_timeout<\/code> raises the cache hit ratio dramatically while keeping the worst-case staleness bounded. If group membership changes must propagate quickly, keep <code>entry_cache_group_timeout<\/code> lower\u2014300 to 600 seconds\u2014rather than lowering every timeout. Restart SSSD after edits and confirm it parsed: <code>sssd --genconf<\/code> plus <code>journalctl -u sssd -n 50 --no-pager<\/code>.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading level=\"2\" -->\n<h2>Verifying Cache Hits<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Configuration without verification is guesswork. SSSD logs at a debug level you control per service, and the NSS responder logs each request with its source and outcome. Raise the level temporarily:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code># temporarily\nsssctl debug-level 8\nsystemctl restart sssd\ngetent passwd deploy &gt;\/dev\/null\ngetent passwd deploy &gt;\/dev\/null\ntail -50 \/var\/log\/sssd\/sssd_nss.log\nsssctl debug-level 0   # back to default<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:paragraph -->\n<p>The first request should show an LDAP fetch, and the second an immediate return from the cache with no network operation. <code>sssctl cache-expire -u deploy<\/code> forces a refresh if you want to test the cache-miss path deliberately. Use <code>sssctl domain-status example.com<\/code> to confirm the domain is online and <code>sssctl user-checks deploy<\/code> to inspect the resolved records.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading level=\"2\" -->\n<h2>Handling Directory Outages Gracefully<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>On a VPS in a different network zone from the directory, brief outages are common. SSSD&#8217;s <code>offline_timeout<\/code> and <code>cache_credentials<\/code> determine whether authentication still works when the server is unreachable. With <code>cache_credentials = true<\/code> and a warm cache, users who logged in recently can authenticate offline; the default <code>krb5_store_password_if_offline<\/code> behaviour is relevant for Kerberos-backed domains.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Also set <code>ldap_network_timeout<\/code> and <code>ldap_opt_timeout<\/code> to short values, typically 3\u20136 seconds, so a silent server does not cause a 30-second stall on first lookup. Pair that with <code>dns_resolver_timeout<\/code> in the domain section and, if you have multiple DCs, list them all in <code>ldap_uri<\/code> so failover is local to SSSD rather than the application.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading level=\"2\" -->\n<h2>What the Improvement Looks Like<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>On a representative 2 vCPU instance with a 45 ms round trip to the directory, moving from direct <code>ldap<\/code> in nsswitch to <code>sss<\/code> with a 600-second memcache typically takes steady-state <code>getent<\/code> from 45\u201360 ms to under 1 ms, and removes the 5-second tails caused by resolver retries. The measurable proxy is a login loop or a request path that performs authorization:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code># before\/after: 200 lookups, report total time\n\/usr\/bin\/time -f 'total %e s' bash -c 'for i in $(seq 1 200); do getent passwd deploy &gt;\/dev\/null; done'\n# group membership lookups are the usual hidden cost\n\/usr\/bin\/time -f 'total %e s' bash -c 'for i in $(seq 1 200); do id deploy &gt;\/dev\/null; done'<\/code><\/pre>\n<!-- \/wp:code -->\n\n<!-- wp:paragraph -->\n<p>If the total barely moves, the cache is not being used\u2014check that <code>sss<\/code> actually precedes any other network module and that <code>memcache_timeout<\/code> is non-zero. On small instances, the CPU saved by avoiding per-request directory queries is often more valuable than the latency win.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Directory-backed authentication is one of the few places where a modest instance can feel fast or slow based purely on configuration, regardless of CPU or memory. If you are choosing a platform for this kind of workload, <a href=\"https:\/\/virtualserversvps.com\/vps-vs-dedicated-server\">our VPS vs dedicated server comparison<\/a> covers the latency and isolation trade-offs. For teams that would rather not own the SSSD tuning and directory integration themselves, it is worth understanding what falls inside and outside a support boundary\u2014<a href=\"https:\/\/virtualserversvps.com\/managed-vs-unmanaged\">compare managed vs unmanaged in our guide<\/a>.<\/p>\n<!-- \/wp:paragraph -->","protected":false},"excerpt":{"rendered":"<p>getent lookups that cost 45 ms each are usually an NSS ordering problem. Configure SSSD memcache and entry timeouts to serve from cache and eliminate LDAP stalls.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":2,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1624","post","type-post","status-publish","format-standard","hentry","category-vps-guides-tutorials"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>NSS and SSSD Caching on a VPS: Killing LDAP Lookup Stalls - Virtual Servers VPS Blog<\/title>\n<meta name=\"description\" content=\"getent lookups that cost 45 ms each are usually an NSS ordering problem. Configure SSSD memcache and entry timeouts to serve from cache and eliminate LDAP stalls.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"NSS and SSSD Caching on a VPS: Killing LDAP Lookup Stalls\" \/>\n<meta property=\"og:description\" content=\"NSS and SSSD Caching on a VPS: Killing LDAP Lookup Stalls\" \/>\n<meta property=\"og:url\" content=\"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/\" \/>\n<meta property=\"og:site_name\" content=\"Virtual Servers VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-11-06T22:23:47+00:00\" \/>\n<meta name=\"author\" content=\"Virtual-Servers-Vps-Editor\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Virtual-Servers-Vps-Editor\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/\",\"name\":\"NSS and SSSD Caching on a VPS: Killing LDAP Lookup Stalls - Virtual Servers VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\"},\"datePublished\":\"2026-11-06T22:23:47+00:00\",\"author\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\"},\"description\":\"getent lookups that cost 45 ms each are usually an NSS ordering problem. Configure SSSD memcache and entry timeouts to serve from cache and eliminate LDAP stalls.\",\"breadcrumb\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/virtualserversvps.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"NSS and SSSD Caching on a VPS: Killing LDAP Lookup Stalls\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/\",\"name\":\"Virtual Servers VPS Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\",\"name\":\"Virtual-Servers-Vps-Editor\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"caption\":\"Virtual-Servers-Vps-Editor\"},\"sameAs\":[\"https:\/\/virtualserversvps.com\/blog\"],\"url\":\"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"NSS and SSSD Caching on a VPS: Killing LDAP Lookup Stalls - Virtual Servers VPS Blog","description":"getent lookups that cost 45 ms each are usually an NSS ordering problem. Configure SSSD memcache and entry timeouts to serve from cache and eliminate LDAP stalls.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/","og_locale":"en_US","og_type":"article","og_title":"NSS and SSSD Caching on a VPS: Killing LDAP Lookup Stalls","og_description":"NSS and SSSD Caching on a VPS: Killing LDAP Lookup Stalls","og_url":"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/","og_site_name":"Virtual Servers VPS Blog","article_published_time":"2026-11-06T22:23:47+00:00","author":"Virtual-Servers-Vps-Editor","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Virtual-Servers-Vps-Editor","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/","url":"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/","name":"NSS and SSSD Caching on a VPS: Killing LDAP Lookup Stalls - Virtual Servers VPS Blog","isPartOf":{"@id":"https:\/\/virtualserversvps.com\/blog\/#website"},"datePublished":"2026-11-06T22:23:47+00:00","author":{"@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0"},"description":"getent lookups that cost 45 ms each are usually an NSS ordering problem. Configure SSSD memcache and entry timeouts to serve from cache and eliminate LDAP stalls.","breadcrumb":{"@id":"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/virtualserversvps.com\/blog\/vps-sssd-nss-caching-ldap-lookup-latency\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/virtualserversvps.com\/blog\/"},{"@type":"ListItem","position":2,"name":"NSS and SSSD Caching on a VPS: Killing LDAP Lookup Stalls"}]},{"@type":"WebSite","@id":"https:\/\/virtualserversvps.com\/blog\/#website","url":"https:\/\/virtualserversvps.com\/blog\/","name":"Virtual Servers VPS Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0","name":"Virtual-Servers-Vps-Editor","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","caption":"Virtual-Servers-Vps-Editor"},"sameAs":["https:\/\/virtualserversvps.com\/blog"],"url":"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/"}]}},"_links":{"self":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1624","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/comments?post=1624"}],"version-history":[{"count":1,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1624\/revisions"}],"predecessor-version":[{"id":1625,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1624\/revisions\/1625"}],"wp:attachment":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/media?parent=1624"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/categories?post=1624"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/tags?post=1624"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}