Measure TLS Handshake and Session Reuse with openssl s_time
Someone asks "is TLS slowing this down", and openssl s_time is the quickest way to get a real number instead of a guess. By the end you will have a repeatable command for timing an SSL/TLS endpoint, plus a second run that shows the effect of reusing sessions. It counts connections and reports bytes read; it is a timing probe, not a general HTTP load tester.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about 10 minutes. You need the OpenSSL command line tools and a host and port you are authorised to test. No elevated privileges are needed for the examples. Benchmarking a third-party service without permission can look like abuse, so use one you operate or a local test server.
1. Check the installed command
The installed binary is OpenSSL 3.6.1 on this machine, but the local manpage is labelled 3.0.13, so lean on the command's own help for the options and defaults your installed binary actually exposes:
$ openssl version
OpenSSL 3.6.1 27 Jan 2026
$ openssl s_time -help
Look for -time, which defaults to 30 seconds, and -connect, whose default is localhost:4433. Set both explicitly in a measurement so an omitted argument never sends the test at an unexpected local service.
Checkpoint
You know the OpenSSL version and have chosen the exact endpoint to test.
2. Run a short handshake-only measurement
Start with a short run that does not request a page. Replace example.net:443 with your authorised endpoint:
$ openssl s_time -connect example.net:443 -time 10 -new
-new measures new connections. The command prints a progress stream followed by a summary like this:
Collecting connection statistics for 10 seconds
...
123 connections in 0.98s; 125.51 connections/user sec, bytes read 0
123 connections in 11 real seconds, 0 bytes read per connection
The exact counts and durations vary with the host, network path, CPU and server load. With no -www option, the measurement covers the TLS handshake but never transfers an application payload, which is handy when you want to separate connection setup from response handling.
This command does not give you the full set of virtual-hosting controls that openssl s_client does. Confirm the endpoint and protocol requirements with the service owner before reading a failed handshake as a performance result.
3. Include a known page and bound the test
Use -www when the test should fetch an HTTP page as part of each connection. A value of / requests the server's default page:
$ openssl s_time -connect example.net:443 -www / -time 10 -new
The summary now includes a non-zero byte count when the server returns data. Transfer size can shift if the page is dynamic, compressed differently or changed mid-run, so for a stable comparison use a small endpoint whose response you control, and record the URL, duration, protocol options and server state alongside the result.
Do not run a long duration while you are still checking syntax. The default is 30 seconds, and a busy endpoint can process many connections in that window. Only stretch the duration once you have permission and a reason to collect more samples.
4. Compare new sessions with reused sessions
Run the same request with -reuse:
$ openssl s_time -connect example.net:443 -www / -time 10 -reuse
This tests whether the connection can reuse the same session ID. The output opens with a line such as Now timing with session id reuse. and uses r characters to show reuse attempts. Compare the connection rate and bytes per connection with the matching -new run, keeping every other test condition the same.
Give this version neither -new nor -reuse and it runs both tests in sequence, a default that is easy to miss in a command copied from shell history. Use one flag for a single clearly labelled measurement, or run both as separate commands for an uncomplicated comparison.
Checkpoint
You have two results with the same endpoint, page, duration and trust settings, differing only in fresh versus reused sessions.
5. Make certificate behaviour explicit
For a normal public HTTPS service, leave certificate verification out of this performance probe unless verification is actually part of the question. To turn it on, give a maximum chain depth:
$ openssl s_time -connect example.net:443 -www / -time 10 -new -verify 5
The manpage records a sharp edge here: verification continues after errors, and a failed server certificate check does not by itself make the connection fail. Treat the reported timing as invalid until you inspect the diagnostic output and verify the certificate separately with a tool built for that job.
For a private service, choose the trust source deliberately:
$ openssl s_time -connect service.example.test:443 -www / -time 10 -new \
-CAfile /path/to/test-ca.pem
-cafile is an obsolete synonym for -CAfile in OpenSSL 3. -cert and -key are for a client certificate and private key, not for trusting the server; a client certificate is only used when the server requests one, so adding -cert alone proves nothing about mutual TLS being configured correctly.
Warning
Never paste a private key into an article, shell transcript or shared ticket. If a key has been exposed, stop the test and rotate it through the service's incident process.
6. Verify a local test without touching a real service
For a safe smoke test, run an OpenSSL test server with a temporary certificate, then point s_time at it. The server command is deliberately local and needs no root:
$ openssl s_server -accept 9443 \
-cert /tmp/s-time-cert.pem -key /tmp/s-time-key.pem -www
$ openssl s_time -connect 127.0.0.1:9443 -www / -time 2 -new \
-no-CAfile -no-CApath -no-CAstore
Expect Collecting connection statistics for 2 seconds, a connection count and a non-zero bytes read value. Repeat the last command with -reuse to exercise the second path. The temporary certificate is intentionally untrusted, and the no-CA options stop this local check from loading the system trust store.
Warning
Stop the test server with Ctrl-C when finished. Remove the temporary key and certificate only if you created them solely for this test and no longer need the evidence. Never delete a path supplied by somebody else.
Common traps
- Connection refused: the host or port is wrong, or nothing is listening. Check the endpoint with the service owner; changing
-timewill not fix it. - Handshake failure: check the server's supported protocol and cipher policy. The command can select
-tls1_2or-tls1_3, but it cannot expose every protocol control thats_clientdoes. - Zero bytes read: you probably omitted
-www, or the server returned no payload. That is not a failed run if handshake-only measurement was the point. - Very different runs: check server load, network path, page size, duration, and whether one run used
-newwhile the other used-reuse. - Unexpected certificate confidence: remember that
-verifyreports chain problems but, by this command's documented behaviour, does not make the connection fail because of them.
Done means
- Version and endpoint recorded. You noted the installed OpenSSL version and an authorised target.
- Flags set explicitly.
-connectand-timewere both given rather than left to defaults. - Scope is clear. You know whether the result measures only handshakes or a full page transfer too.
- Fresh versus reused compared. You ran
-newand-reuseunder matching conditions. - Certificates and keys kept separate. Verification and private key handling were treated as distinct concerns.
- Cleaned up. Any local test server was stopped and no temporary secret kept unnecessarily.