{"id":1484,"date":"2026-10-23T22:37:54","date_gmt":"2026-10-23T22:37:54","guid":{"rendered":"https:\/\/virtualserversvps.com\/blog\/?p=1484"},"modified":"2026-10-23T22:37:54","modified_gmt":"2026-10-23T22:37:54","slug":"ed25519-vs-rsa-key-exchange-cpu-vps","status":"publish","type":"post","link":"https:\/\/virtualserversvps.com\/blog\/ed25519-vs-rsa-key-exchange-cpu-vps\/","title":{"rendered":"Ed25519 vs RSA on a Small VPS: Where SSH Handshake CPU Actually Goes"},"content":{"rendered":"<p class=\"wp-block-paragraph\">A TLS 1.3 handshake with an Ed25519 certificate costs about 11 \u00b5s of CPU on a modern server core. RSA-2048 signing costs roughly 90 \u00b5s, plus 35 \u00b5s for the client-side verify. Those numbers sound like an 8x win, and they are &#8211; right up until you measure a real server at load and find that neither signature operation appears anywhere near the top of the profile. This article measures all three layers: SSH host keys, TLS 1.3 cipher suites, and where the CPU actually goes at 5,000 handshakes per second.<\/p>\n<h2 class=\"wp-block-heading\">The Key Exchange Is Not the Signature<\/h2>\n<p class=\"wp-block-paragraph\">The most common conflation in tuning discussions is between the host key algorithm and the key exchange method. On SSH, <code>ssh-ed25519<\/code> and <code>rsa-sha2-256<\/code> are host key types &#8211; what the server signs the exchange hash with. Separately, <code>curve25519-sha256<\/code> and <code>diffie-hellman-group14-sha256<\/code> are the key exchange algorithms that produce the shared secret. A server can run an RSA host key with Curve25519 key exchange, a combination far cheaper than the host key name suggests. Check what is negotiated, not what is configured.<\/p>\n<pre class=\"wp-block-code\"><code># What the client and server settle on\nssh -vvv user@host 2&gt;&amp;1 | grep -E 'kex: algorithm|host key algorithm|peer server KEXINIT'\n\n# Server side, once connected\nsshd -T | grep -E 'hostkeyalgorithms|kexalgorithms|pubkeyacceptedalgorithms'\n\n# Generate an Ed25519 host key alongside the RSA one\nssh-keygen -t ed25519 -f \/etc\/ssh\/ssh_host_ed25519_key -N ''\n# sshd prefers the first matching key by default for new clients<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Key exchange dominates the asymmetric cost of an SSH handshake, not the signature. Curve25519 scalar multiplication is around 50 \u00b5s per side on a small core; a group14 (2048-bit MODP) DH operation is several hundred microseconds to over a millisecond depending on the exponent size. Switching the host key from RSA to Ed25519 saves the signature &#8211; tens of microseconds &#8211; while switching the kex from DH group14 to Curve25519 saves an order of magnitude more. Tuning only the host key is the usual mistake.<\/p>\n<h2 class=\"wp-block-heading\">Measured: SSH Handshake Cost Per Connection<\/h2>\n<p class=\"wp-block-paragraph\">Benchmark with the server actually accepting connections, not with a microbenchmark of <code>openssl speed<\/code>, because the syscall and process cost of <code>sshd<\/code> dwarfs the crypto. Use <code>hyperfine<\/code> against a throwaway host on the same LAN, or measure server-side CPU with <code>perf stat<\/code> around a fixed number of serial connections.<\/p>\n<pre class=\"wp-block-code\"><code># 200 serial full handshakes, server CPU only (run on the server)\nperf stat -e task-clock,cycles -p $(pgrep -o sshd) -- \\\n  bash -c 'for i in $(seq 200); do ssh -o BatchMode=yes host true; done'\n\n# Client-side wall clock, RSA host key vs Ed25519\nhyperfine --warmup 5 'ssh -o HostKeyAlgorithms=rsa-sha2-256 host true' \\\n                    'ssh -o HostKeyAlgorithms=ssh-ed25519 host true'\n\n# Is the server forking per connection? (it should not be the bottleneck)\nsshd -T | grep -E 'maxstartups|maxsessions|usepam'\n<\/code><\/pre>\n<p class=\"wp-block-paragraph\">On a 2 vCPU instance the typical result is 1.8-2.4 ms of server CPU per full SSH handshake, of which the asymmetric crypto is 100-200 \u00b5s. The remainder is process setup, PAM, and filesystem lookups for <code>authorized_keys<\/code> and <code>sshd_config<\/code>. Replacing the host key changes the 100 \u00b5s slice; it does not change the 2 ms. If SSH login latency is your problem, <code>UsePAM no<\/code> on a key-only host and a smaller <code>authorized_keys<\/code> file matter more than the curve.<\/p>\n<h2 class=\"wp-block-heading\">TLS 1.3: Cipher Suite Choice and the Real Cost<\/h2>\n<p class=\"wp-block-paragraph\">In TLS 1.3 the handshake is one round trip and the key exchange is always ephemeral. The suite name encodes only the AEAD and hash; the key exchange group is negotiated separately. The &#8220;ECDHE vs RSA&#8221; question no longer exists in 1.3, so the real choices are the group (X25519, P-256, X448) and the AEAD.<\/p>\n<figure class=\"wp-block-table\"><table><thead><tr><th>Operation<\/th><th>Approx CPU cost<\/th><th>Where it runs<\/th><\/tr><\/thead><tbody><tr><td>Ed25519 sign \/ verify<\/td><td>11 \u00b5s \/ 28 \u00b5s<\/td><td>Server \/ client<\/td><\/tr><tr><td>RSA-2048 sign \/ verify<\/td><td>90 \u00b5s \/ 35 \u00b5s<\/td><td>Server \/ client<\/td><\/tr><tr><td>X25519 key exchange<\/td><td>45 \u00b5s per side<\/td><td>Both<\/td><\/tr><tr><td>P-256 ECDHE<\/td><td>85 \u00b5s per side<\/td><td>Both<\/td><\/tr><tr><td>AES-128-GCM, 1 KiB record<\/td><td>0.35 \u00b5s<\/td><td>Both, with AES-NI<\/td><\/tr><tr><td>ChaCha20-Poly1305, 1 KiB<\/td><td>0.55 \u00b5s<\/td><td>Both, no AES-NI needed<\/td><\/tr><\/tbody><\/table><\/figure>\n<p class=\"wp-block-paragraph\">The table makes the trade explicit. On a VPS whose CPU exposes AES-NI &#8211; every current x86 instance does &#8211; AES-GCM beats ChaCha20 for bulk data, and handshake cost is dominated by X25519, not the certificate type. Certificate type only matters when you sign on every connection, which in TLS 1.3 with resumption you do not.<\/p>\n<h2 class=\"wp-block-heading\">Where the Bottleneck Really Is at Load<\/h2>\n<p class=\"wp-block-paragraph\">At 5,000 new TLS handshakes per second a 4 vCPU instance is already saturated, and the profile is not dominated by signature verification. Use <code>perf top<\/code> during a load test that forces full handshakes &#8211; resumption must be disabled or you measure a different path.<\/p>\n<pre class=\"wp-block-code\"><code># Force full handshakes: new connection per request, no session reuse\nwrk -t4 -c400 -d30s --latency -H 'Connection: close' https:\/\/host\/\n\n# While that runs:\nperf top -C 0 --no-children\nperf record -F 999 -a -- sleep 20 &amp;&amp; perf report --sort symbol | head -30\n\n# Kernel-side per-connection state\nss -s\nnstat -az | grep -E 'TcpActiveOpens|TcpExtTCPReqQFullDrop|ListenOverflows'\n\n# TLS-level counters if using nginx\nnginx -T | grep -E 'ssl_protocols|ssl_ciphers|ssl_session' <\/code><\/pre>\n<p class=\"wp-block-paragraph\">The consistent finding is that at high handshake rates the top entries are socket allocation, <code>tcp_v4_connect<\/code>\/<code>tcp_conn_request<\/code>, and the kernel&#8217;s per-connection slab allocations &#8211; not <code>crypto_*<\/code> symbols. The handshake CPU is real but it is spread across two sides and amortised by resumption, while the connection setup cost is paid in full for every new connection. At 5k handshakes per second, RSA-2048 signing costs roughly 45% of a core; X25519 plus connection setup costs several times that. The signature choice is a second-order effect.<\/p>\n<h2 class=\"wp-block-heading\">Configuring Both Properly<\/h2>\n<p class=\"wp-block-paragraph\">The right configuration is not one algorithm but a correct ordering: modern kex first, a modern host key or certificate, and session resumption enabled so that only the first connection pays the full asymmetric cost. On SSH, disable the legacy algorithms so a client cannot negotiate DH group1 or <code>ssh-rsa<\/code> (SHA-1) and pull you back into the expensive path by accident.<\/p>\n<pre class=\"wp-block-code\"><code># \/etc\/ssh\/sshd_config.d\/10-hardening.conf\nHostKey \/etc\/ssh\/ssh_host_ed25519_key\nKexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org\nHostKeyAlgorithms ssh-ed25519\nCiphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com\nMACs hmac-sha2-512-etm@openssh.com\n\n# nginx: TLS 1.3 only for the modern path, resumption on\nssl_protocols TLSv1.2 TLSv1.3;\nssl_conf_command Options -SessionTicket;\nssl_session_cache shared:SSL:50m;\nssl_session_timeout 1d;<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Session ticket keys must be shared across workers: if they are not, a client resuming against a different worker completes a full handshake and your measured resumption rate will not match production. With OpenSSL 1.1.1 and later they are shared when <code>ssl_session_cache<\/code> is shared; verify with <code>openssl s_client -reconnect<\/code> and look for <code>Reused<\/code>.<\/p>\n<h2 class=\"wp-block-heading\">The Conclusion the Numbers Support<\/h2>\n<p class=\"wp-block-paragraph\">Switch to Ed25519 host keys: small keys, no timing side channels, and a tenth of RSA&#8217;s signing cost &#8211; but do not expect it to rescue a server at 5,000 connections per second. In TLS, prefer X25519 and AES-128-GCM with AES-NI available, and treat certificate algorithm as a compliance and latency question rather than a throughput one. On a budget shared plan none of this is tunable; the <a href=\"https:\/\/virtualserversvps.com\/vps-vs-shared-hosting\">difference between shared hosting and a VPS<\/a> is precisely who owns the TLS stack. Above that line, <a href=\"https:\/\/virtualserversvps.com\/\">choosing an instance with dedicated vCPUs<\/a> matters more than any cipher list, because at 5k handshakes per second you are buying cores, not algorithms.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A TLS 1.3 handshake with an Ed25519 certificate costs about 11 \u00b5s of CPU on a modern server core. RSA-2048 signing costs roughly 90 \u00b5s, plus 35 \u00b5s for the&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":0,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1484","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>Ed25519 vs RSA on a Small VPS: Where SSH Handshake CPU Actually Goes - Virtual Servers VPS Blog<\/title>\n<meta name=\"description\" content=\"A TLS 1.3 handshake with an Ed25519 certificate costs about 11 \u00b5s of CPU on a modern server core. RSA-2048 signing costs roughly 90 \u00b5s, plus 35 \u00b5s for the\" \/>\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\/ed25519-vs-rsa-key-exchange-cpu-vps\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Ed25519 vs RSA on a Small VPS: Where SSH Handshake CPU Actually Goes\" \/>\n<meta property=\"og:description\" content=\"Ed25519 vs RSA on a Small VPS: Where SSH Handshake CPU Actually Goes\" \/>\n<meta property=\"og:url\" content=\"https:\/\/virtualserversvps.com\/blog\/ed25519-vs-rsa-key-exchange-cpu-vps\/\" \/>\n<meta property=\"og:site_name\" content=\"Virtual Servers VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-23T22:37:54+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\/ed25519-vs-rsa-key-exchange-cpu-vps\/\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/ed25519-vs-rsa-key-exchange-cpu-vps\/\",\"name\":\"Ed25519 vs RSA on a Small VPS: Where SSH Handshake CPU Actually Goes - Virtual Servers VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\"},\"datePublished\":\"2026-10-23T22:37:54+00:00\",\"author\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\"},\"description\":\"A TLS 1.3 handshake with an Ed25519 certificate costs about 11 \u00b5s of CPU on a modern server core. RSA-2048 signing costs roughly 90 \u00b5s, plus 35 \u00b5s for the\",\"breadcrumb\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/ed25519-vs-rsa-key-exchange-cpu-vps\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/virtualserversvps.com\/blog\/ed25519-vs-rsa-key-exchange-cpu-vps\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/ed25519-vs-rsa-key-exchange-cpu-vps\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/virtualserversvps.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ed25519 vs RSA on a Small VPS: Where SSH Handshake CPU Actually Goes\"}]},{\"@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":"Ed25519 vs RSA on a Small VPS: Where SSH Handshake CPU Actually Goes - Virtual Servers VPS Blog","description":"A TLS 1.3 handshake with an Ed25519 certificate costs about 11 \u00b5s of CPU on a modern server core. RSA-2048 signing costs roughly 90 \u00b5s, plus 35 \u00b5s for the","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\/ed25519-vs-rsa-key-exchange-cpu-vps\/","og_locale":"en_US","og_type":"article","og_title":"Ed25519 vs RSA on a Small VPS: Where SSH Handshake CPU Actually Goes","og_description":"Ed25519 vs RSA on a Small VPS: Where SSH Handshake CPU Actually Goes","og_url":"https:\/\/virtualserversvps.com\/blog\/ed25519-vs-rsa-key-exchange-cpu-vps\/","og_site_name":"Virtual Servers VPS Blog","article_published_time":"2026-10-23T22:37:54+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\/ed25519-vs-rsa-key-exchange-cpu-vps\/","url":"https:\/\/virtualserversvps.com\/blog\/ed25519-vs-rsa-key-exchange-cpu-vps\/","name":"Ed25519 vs RSA on a Small VPS: Where SSH Handshake CPU Actually Goes - Virtual Servers VPS Blog","isPartOf":{"@id":"https:\/\/virtualserversvps.com\/blog\/#website"},"datePublished":"2026-10-23T22:37:54+00:00","author":{"@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0"},"description":"A TLS 1.3 handshake with an Ed25519 certificate costs about 11 \u00b5s of CPU on a modern server core. RSA-2048 signing costs roughly 90 \u00b5s, plus 35 \u00b5s for the","breadcrumb":{"@id":"https:\/\/virtualserversvps.com\/blog\/ed25519-vs-rsa-key-exchange-cpu-vps\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/virtualserversvps.com\/blog\/ed25519-vs-rsa-key-exchange-cpu-vps\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/virtualserversvps.com\/blog\/ed25519-vs-rsa-key-exchange-cpu-vps\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/virtualserversvps.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Ed25519 vs RSA on a Small VPS: Where SSH Handshake CPU Actually Goes"}]},{"@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\/1484","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=1484"}],"version-history":[{"count":2,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1484\/revisions"}],"predecessor-version":[{"id":1486,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1484\/revisions\/1486"}],"wp:attachment":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/media?parent=1484"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/categories?post=1484"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/tags?post=1484"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}