{"kind": "tool", "major": "18", "item": {"slug": "pg-test-timing", "name": "pg_test_timing", "name_zh": "", "category": "Server applications", "summary": "pg_test_timing \u2014 measure timing overhead", "aliases": ["pg_test_timing"], "content_hash": "21e6221cf5509bc88df83b6c4dfd455fd51cedd692657f576934511931c9080d", "versions": {"10": {"facts": [{"label": "Documented executable", "value": "pg_test_timing"}, {"label": "Executable version", "value": "10.23"}, {"label": "Reference inventory", "value": "Server applications"}, {"label": "Option definition groups", "value": "3"}], "tables": [{"key": "options", "rows": [{"summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": {"url": "/docs/10/pgtesttiming.html", "text": "-d duration --duration= duration"}}, {"summary": "Print the pg_test_timing version and exit.", "signature": {"url": "/docs/10/pgtesttiming.html", "text": "-V --version"}}, {"summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": {"url": "/docs/10/pgtesttiming.html", "text": "-? --help"}}], "title": "Documented options", "columns": [{"key": "signature", "label": "Option and arguments"}, {"key": "summary", "label": "Description"}]}], "options": [{"names": ["-d duration", "--duration= duration"], "summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": "-d duration --duration= duration", "source_url": "/docs/10/pgtesttiming.html", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "summary": "Print the pg_test_timing version and exit.", "signature": "-V --version", "source_url": "/docs/10/pgtesttiming.html", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": "-? --help", "source_url": "/docs/10/pgtesttiming.html", "description": "Show help about pg_test_timing command line arguments, and exit."}], "related": [], "release": {"ref": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "label": "10.23", "major": "10", "channel": "historical", "manifest": {"pdf": {"A4": {"url": "/files/documentation/pdf/10/postgresql-10-A4.pdf", "bytes": 12631706, "pages": 2591, "sha256": "34497ab9efb45c5bdf1bd11b9016b5451354feb462fa029cf74557a5fa5fbbc1", "built_at": "2026-09-26"}, "US": {"url": "/files/documentation/pdf/10/postgresql-10-US.pdf", "bytes": 12531684, "pages": 2724, "sha256": "429cc7133ddf4f97c560aa466dc9caea4b718721a8321e293357037cf0af4733", "built_at": "2026-09-26"}}, "tree": "10", "index": "index.html", "major": "10", "pages": 1085, "release": "10.23", "source_url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "svg_assets": 0, "source_mode": "en HTML verified against the pinned official archive", "source_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}, "revision": "f9301feba91e2e2566038a36b8cee0e4402db68989538f88670fddd20b1f78ea", "evidence_kind": "English manual and source declarations", "source_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}, "sources": [{"url": "/docs/10/pgtesttiming.html", "file": "pgtesttiming.html", "label": "10.23 English manual \u00b7 pgtesttiming.html", "anchor": "", "sha256": "0bdb475e62d4df7fe49b4793db515a22662c10d4c0d9b1ac3c05a17baeee801c"}, {"url": "/docs/10/reference-server.html", "file": "reference-server.html", "label": "Server applications inventory", "anchor": "", "sha256": "2a6043b88501763a31348758a370a42cd7f9a179c7fdf3ef0e353c82e95b33e9"}], "sections": [], "synopsis": ["pg_test_timing [ option ...]"], "signature": "pg_test_timing [ option ...]", "description": ["pg_test_timing \u2014 measure timing overhead"], "environment": [], "manual_html": "<div><div class=\"refentry\" id=\"PGTESTTIMING\">\n<div class=\"titlepage\"></div>\n\n<div class=\"refnamediv\">\n<h2><span class=\"refentrytitle\"><span class=\"application\">pg_test_timing</span></span></h2>\n<p>pg_test_timing \u2014 measure timing overhead</p>\n</div>\n<div class=\"refsynopsisdiv\">\n<h2>Synopsis</h2>\n<div class=\"cmdsynopsis\">\n<p id=\"id-1.9.5.10.4.1\"><code class=\"command\">pg_test_timing</code> [<em class=\"replaceable\"><code>option</code></em>...]</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.10.5\">\n<h2>Description</h2>\n<p><span class=\"application\">pg_test_timing</span> is a tool to measure the timing overhead on your system and confirm that the system time never moves backwards. Systems that are slow to collect timing data can give less accurate <code class=\"command\">EXPLAIN ANALYZE</code> results.</p>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.10.6\">\n<h2>Options</h2>\n<p><span class=\"application\">pg_test_timing</span> accepts the following command-line options:</p>\n<div class=\"variablelist\">\n<dl class=\"variablelist\">\n<dt><span class=\"term\"><code class=\"option\">-d <em class=\"replaceable\"><code>duration</code></em></code><br></span><span class=\"term\"><code class=\"option\">--duration=<em class=\"replaceable\"><code>duration</code></em></code></span></dt>\n<dd>\n<p>Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-V</code><br></span><span class=\"term\"><code class=\"option\">--version</code></span></dt>\n<dd>\n<p>Print the <span class=\"application\">pg_test_timing</span> version and exit.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-?</code><br></span><span class=\"term\"><code class=\"option\">--help</code></span></dt>\n<dd>\n<p>Show help about <span class=\"application\">pg_test_timing</span> command line arguments, and exit.</p>\n</dd>\n</dl>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.10.7\">\n<h2>Usage</h2>\n<div class=\"refsect2\" id=\"id-1.9.5.10.7.2\">\n<h3>Interpreting results</h3>\n<p>Good results will show most (&gt;90%) individual timing calls take less than one microsecond. Average per loop overhead will be even lower, below 100 nanoseconds. This example from an Intel i7-860 system using a TSC clock source shows excellent performance:</p>\n<pre class=\"screen\">Testing timing overhead for 3 seconds.\nPer loop time including overhead: 35.96 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     96.40465   80435604\n     2      3.59518    2999652\n     4      0.00015        126\n     8      0.00002         13\n    16      0.00000          2\n</pre>\n<p>Note that different units are used for the per loop time than the histogram. The loop can have resolution within a few nanoseconds (ns), while the individual timing calls can only resolve down to one microsecond (us).</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.10.7.3\">\n<h3>Measuring executor timing overhead</h3>\n<p>When the query executor is running a statement using <code class=\"command\">EXPLAIN ANALYZE</code>, individual operations are timed as well as showing a summary. The overhead of your system can be checked by counting rows with the <span class=\"application\">psql</span> program:</p>\n<pre class=\"screen\">CREATE TABLE t AS SELECT * FROM generate_series(1,100000);\n\\timing\nSELECT COUNT(*) FROM t;\nEXPLAIN ANALYZE SELECT COUNT(*) FROM t;\n</pre>\n<p>The i7-860 system measured runs the count query in 9.8 ms while the <code class=\"command\">EXPLAIN ANALYZE</code> version takes 16.6 ms, each processing just over 100,000 rows. That 6.8 ms difference means the timing overhead per row is 68 ns, about twice what pg_test_timing estimated it would be. Even that relatively small amount of overhead is making the fully timed count statement take almost 70% longer. On more substantial queries, the timing overhead would be less problematic.</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.10.7.4\">\n<h3>Changing time sources</h3>\n<p>On some newer Linux systems, it's possible to change the clock source used to collect timing data at any time. A second example shows the slowdown possible from switching to the slower acpi_pm time source, on the same system used for the fast results above:</p>\n<pre class=\"screen\"># cat /sys/devices/system/clocksource/clocksource0/available_clocksource\ntsc hpet acpi_pm\n# echo acpi_pm &gt; /sys/devices/system/clocksource/clocksource0/current_clocksource\n# pg_test_timing\nPer loop time including overhead: 722.92 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     27.84870    1155682\n     2     72.05956    2990371\n     4      0.07810       3241\n     8      0.01357        563\n    16      0.00007          3\n</pre>\n<p>In this configuration, the sample <code class=\"command\">EXPLAIN ANALYZE</code> above takes 115.9 ms. That's 1061 ns of timing overhead, again a small multiple of what's measured directly by this utility. That much timing overhead means the actual query itself is only taking a tiny fraction of the accounted for time, most of it is being consumed in overhead instead. In this configuration, any <code class=\"command\">EXPLAIN ANALYZE</code> totals involving many timed operations would be inflated significantly by timing overhead.</p>\n<p>FreeBSD also allows changing the time source on the fly, and it logs information about the timer selected during boot:</p>\n<pre class=\"screen\"># dmesg | grep \"Timecounter\"\nTimecounter \"ACPI-fast\" frequency 3579545 Hz quality 900\nTimecounter \"i8254\" frequency 1193182 Hz quality 0\nTimecounters tick every 10.000 msec\nTimecounter \"TSC\" frequency 2531787134 Hz quality 800\n# sysctl kern.timecounter.hardware=TSC\nkern.timecounter.hardware: ACPI-fast -&gt; TSC\n</pre>\n<p>Other systems may only allow setting the time source on boot. On older Linux systems the \"clock\" kernel setting is the only way to make this sort of change. And even on some more recent ones, the only option you'll see for a clock source is \"jiffies\". Jiffies are the older Linux software clock implementation, which can have good resolution when it's backed by fast enough timing hardware, as in this example:</p>\n<pre class=\"screen\">$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource\njiffies\n$ dmesg | grep time.c\ntime.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.\ntime.c: Detected 2400.153 MHz processor.\n$ pg_test_timing\nTesting timing overhead for 3 seconds.\nPer timing duration including loop overhead: 97.75 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     90.23734   27694571\n     2      9.75277    2993204\n     4      0.00981       3010\n     8      0.00007         22\n    16      0.00000          1\n    32      0.00000          1\n</pre></div>\n<div class=\"refsect2\" id=\"id-1.9.5.10.7.5\">\n<h3>Clock hardware and timing accuracy</h3>\n<p>Collecting accurate timing information is normally done on computers using hardware clocks with various levels of accuracy. With some hardware the operating systems can pass the system clock time almost directly to programs. A system clock can also be derived from a chip that simply provides timing interrupts, periodic ticks at some known time interval. In either case, operating system kernels provide a clock source that hides these details. But the accuracy of that clock source and how quickly it can return results varies based on the underlying hardware.</p>\n<p>Inaccurate time keeping can result in system instability. Test any change to the clock source very carefully. Operating system defaults are sometimes made to favor reliability over best accuracy. And if you are using a virtual machine, look into the recommended time sources compatible with it. Virtual hardware faces additional difficulties when emulating timers, and there are often per operating system settings suggested by vendors.</p>\n<p>The Time Stamp Counter (TSC) clock source is the most accurate one available on current generation CPUs. It's the preferred way to track the system time when it's supported by the operating system and the TSC clock is reliable. There are several ways that TSC can fail to provide an accurate timing source, making it unreliable. Older systems can have a TSC clock that varies based on the CPU temperature, making it unusable for timing. Trying to use TSC on some older multicore CPUs can give a reported time that's inconsistent among multiple cores. This can result in the time going backwards, a problem this program checks for. And even the newest systems can fail to provide accurate TSC timing with very aggressive power saving configurations.</p>\n<p>Newer operating systems may check for the known TSC problems and switch to a slower, more stable clock source when they are seen. If your system supports TSC time but doesn't default to that, it may be disabled for a good reason. And some operating systems may not detect all the possible problems correctly, or will allow using TSC even in situations where it's known to be inaccurate.</p>\n<p>The High Precision Event Timer (HPET) is the preferred timer on systems where it's available and TSC is not accurate. The timer chip itself is programmable to allow up to 100 nanosecond resolution, but you may not see that much accuracy in your system clock.</p>\n<p>Advanced Configuration and Power Interface (ACPI) provides a Power Management (PM) Timer, which Linux refers to as the acpi_pm. The clock derived from acpi_pm will at best provide 300 nanosecond resolution.</p>\n<p>Timers used on older PC hardware include the 8254 Programmable Interval Timer (PIT), the real-time clock (RTC), the Advanced Programmable Interrupt Controller (APIC) timer, and the Cyclone timer. These timers aim for millisecond resolution.</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.10.8\">\n<h2>See Also</h2>\n<span class=\"simplelist\"><a class=\"xref\" href=\"/docs/10/sql-explain.html\" title=\"EXPLAIN\"><span class=\"refentrytitle\">EXPLAIN</span></a></span></div>\n</div></div>", "manual_path": "pgtesttiming.html", "comparison_data": {"options": [{"names": ["-d duration", "--duration= duration"], "signature": "-d duration --duration= duration", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "signature": "-V --version", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "signature": "-? --help", "description": "Show help about pg_test_timing command line arguments, and exit."}], "synopsis": ["pg_test_timing [ option ...]"], "environment": []}, "comparison_hash": "1e9850049374c38671166c0a5cf0759d6f33dd01f733985211c9962ac16213b4"}, "11": {"facts": [{"label": "Documented executable", "value": "pg_test_timing"}, {"label": "Executable version", "value": "11.22"}, {"label": "Reference inventory", "value": "Server applications"}, {"label": "Option definition groups", "value": "3"}], "tables": [{"key": "options", "rows": [{"summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": {"url": "/docs/11/pgtesttiming.html", "text": "-d duration --duration= duration"}}, {"summary": "Print the pg_test_timing version and exit.", "signature": {"url": "/docs/11/pgtesttiming.html", "text": "-V --version"}}, {"summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": {"url": "/docs/11/pgtesttiming.html", "text": "-? --help"}}], "title": "Documented options", "columns": [{"key": "signature", "label": "Option and arguments"}, {"key": "summary", "label": "Description"}]}], "options": [{"names": ["-d duration", "--duration= duration"], "summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": "-d duration --duration= duration", "source_url": "/docs/11/pgtesttiming.html", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "summary": "Print the pg_test_timing version and exit.", "signature": "-V --version", "source_url": "/docs/11/pgtesttiming.html", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": "-? --help", "source_url": "/docs/11/pgtesttiming.html", "description": "Show help about pg_test_timing command line arguments, and exit."}], "related": [], "release": {"ref": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "label": "11.22", "major": "11", "channel": "historical", "manifest": {"pdf": {"A4": {"url": "/files/documentation/pdf/11/postgresql-11-A4.pdf", "bytes": 13057499, "pages": 2732, "sha256": "41d75855e610d0d9b8802b87dc5b080bef8d7e91c7cf69401fbf8d3cf801b4b5", "built_at": "2026-09-26"}, "US": {"url": "/files/documentation/pdf/11/postgresql-11-US.pdf", "bytes": 12961189, "pages": 2883, "sha256": "6a8899ef36935a5b7ed2b436207564a567a4ef1eb1c2200195876b8de4d4fa30", "built_at": "2026-09-26"}}, "tree": "11", "index": "index.html", "major": "11", "pages": 1125, "release": "11.22", "source_url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "svg_assets": 0, "source_mode": "en HTML verified against the pinned official archive", "source_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}, "revision": "53315ddaf3b3f9e6669fd1edc096bbb2cd4a65ea3e836c89e542b43af9ba3a7f", "evidence_kind": "English manual and source declarations", "source_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}, "sources": [{"url": "/docs/11/pgtesttiming.html", "file": "pgtesttiming.html", "label": "11.22 English manual \u00b7 pgtesttiming.html", "anchor": "", "sha256": "8a6e9c0d08732289559266b03ae7474dfcf9ea0591bcae5f1ba7653102ab0716"}, {"url": "/docs/11/reference-server.html", "file": "reference-server.html", "label": "Server applications inventory", "anchor": "", "sha256": "e940a8505b6742c717a1683d19bf8f759aad245633a59db9e83a345ae7c5709a"}], "sections": [], "synopsis": ["pg_test_timing [ option ...]"], "signature": "pg_test_timing [ option ...]", "description": ["pg_test_timing \u2014 measure timing overhead"], "environment": [], "manual_html": "<div><div class=\"refentry\" id=\"PGTESTTIMING\">\n<div class=\"titlepage\"></div>\n<div class=\"refnamediv\">\n<h2><span class=\"refentrytitle\"><span class=\"application\">pg_test_timing</span></span></h2>\n<p>pg_test_timing \u2014 measure timing overhead</p>\n</div>\n<div class=\"refsynopsisdiv\">\n<h2>Synopsis</h2>\n<div class=\"cmdsynopsis\">\n<p id=\"id-1.9.5.10.4.1\"><code class=\"command\">pg_test_timing</code> [<em class=\"replaceable\"><code>option</code></em>...]</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.10.5\">\n<h2>Description</h2>\n<p><span class=\"application\">pg_test_timing</span> is a tool to measure the timing overhead on your system and confirm that the system time never moves backwards. Systems that are slow to collect timing data can give less accurate <code class=\"command\">EXPLAIN ANALYZE</code> results.</p>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.10.6\">\n<h2>Options</h2>\n<p><span class=\"application\">pg_test_timing</span> accepts the following command-line options:</p>\n<div class=\"variablelist\">\n<dl class=\"variablelist\">\n<dt><span class=\"term\"><code class=\"option\">-d <em class=\"replaceable\"><code>duration</code></em></code><br></span><span class=\"term\"><code class=\"option\">--duration=<em class=\"replaceable\"><code>duration</code></em></code></span></dt>\n<dd>\n<p>Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-V</code><br></span><span class=\"term\"><code class=\"option\">--version</code></span></dt>\n<dd>\n<p>Print the <span class=\"application\">pg_test_timing</span> version and exit.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-?</code><br></span><span class=\"term\"><code class=\"option\">--help</code></span></dt>\n<dd>\n<p>Show help about <span class=\"application\">pg_test_timing</span> command line arguments, and exit.</p>\n</dd>\n</dl>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.10.7\">\n<h2>Usage</h2>\n<div class=\"refsect2\" id=\"id-1.9.5.10.7.2\">\n<h3>Interpreting results</h3>\n<p>Good results will show most (&gt;90%) individual timing calls take less than one microsecond. Average per loop overhead will be even lower, below 100 nanoseconds. This example from an Intel i7-860 system using a TSC clock source shows excellent performance:</p>\n<pre class=\"screen\">Testing timing overhead for 3 seconds.\nPer loop time including overhead: 35.96 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     96.40465   80435604\n     2      3.59518    2999652\n     4      0.00015        126\n     8      0.00002         13\n    16      0.00000          2\n</pre>\n<p>Note that different units are used for the per loop time than the histogram. The loop can have resolution within a few nanoseconds (ns), while the individual timing calls can only resolve down to one microsecond (us).</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.10.7.3\">\n<h3>Measuring executor timing overhead</h3>\n<p>When the query executor is running a statement using <code class=\"command\">EXPLAIN ANALYZE</code>, individual operations are timed as well as showing a summary. The overhead of your system can be checked by counting rows with the <span class=\"application\">psql</span> program:</p>\n<pre class=\"screen\">CREATE TABLE t AS SELECT * FROM generate_series(1,100000);\n\\timing\nSELECT COUNT(*) FROM t;\nEXPLAIN ANALYZE SELECT COUNT(*) FROM t;\n</pre>\n<p>The i7-860 system measured runs the count query in 9.8 ms while the <code class=\"command\">EXPLAIN ANALYZE</code> version takes 16.6 ms, each processing just over 100,000 rows. That 6.8 ms difference means the timing overhead per row is 68 ns, about twice what pg_test_timing estimated it would be. Even that relatively small amount of overhead is making the fully timed count statement take almost 70% longer. On more substantial queries, the timing overhead would be less problematic.</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.10.7.4\">\n<h3>Changing time sources</h3>\n<p>On some newer Linux systems, it's possible to change the clock source used to collect timing data at any time. A second example shows the slowdown possible from switching to the slower acpi_pm time source, on the same system used for the fast results above:</p>\n<pre class=\"screen\"># cat /sys/devices/system/clocksource/clocksource0/available_clocksource\ntsc hpet acpi_pm\n# echo acpi_pm &gt; /sys/devices/system/clocksource/clocksource0/current_clocksource\n# pg_test_timing\nPer loop time including overhead: 722.92 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     27.84870    1155682\n     2     72.05956    2990371\n     4      0.07810       3241\n     8      0.01357        563\n    16      0.00007          3\n</pre>\n<p>In this configuration, the sample <code class=\"command\">EXPLAIN ANALYZE</code> above takes 115.9 ms. That's 1061 ns of timing overhead, again a small multiple of what's measured directly by this utility. That much timing overhead means the actual query itself is only taking a tiny fraction of the accounted for time, most of it is being consumed in overhead instead. In this configuration, any <code class=\"command\">EXPLAIN ANALYZE</code> totals involving many timed operations would be inflated significantly by timing overhead.</p>\n<p>FreeBSD also allows changing the time source on the fly, and it logs information about the timer selected during boot:</p>\n<pre class=\"screen\"># dmesg | grep \"Timecounter\"\nTimecounter \"ACPI-fast\" frequency 3579545 Hz quality 900\nTimecounter \"i8254\" frequency 1193182 Hz quality 0\nTimecounters tick every 10.000 msec\nTimecounter \"TSC\" frequency 2531787134 Hz quality 800\n# sysctl kern.timecounter.hardware=TSC\nkern.timecounter.hardware: ACPI-fast -&gt; TSC\n</pre>\n<p>Other systems may only allow setting the time source on boot. On older Linux systems the \"clock\" kernel setting is the only way to make this sort of change. And even on some more recent ones, the only option you'll see for a clock source is \"jiffies\". Jiffies are the older Linux software clock implementation, which can have good resolution when it's backed by fast enough timing hardware, as in this example:</p>\n<pre class=\"screen\">$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource\njiffies\n$ dmesg | grep time.c\ntime.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.\ntime.c: Detected 2400.153 MHz processor.\n$ pg_test_timing\nTesting timing overhead for 3 seconds.\nPer timing duration including loop overhead: 97.75 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     90.23734   27694571\n     2      9.75277    2993204\n     4      0.00981       3010\n     8      0.00007         22\n    16      0.00000          1\n    32      0.00000          1\n</pre>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.10.7.5\">\n<h3>Clock hardware and timing accuracy</h3>\n<p>Collecting accurate timing information is normally done on computers using hardware clocks with various levels of accuracy. With some hardware the operating systems can pass the system clock time almost directly to programs. A system clock can also be derived from a chip that simply provides timing interrupts, periodic ticks at some known time interval. In either case, operating system kernels provide a clock source that hides these details. But the accuracy of that clock source and how quickly it can return results varies based on the underlying hardware.</p>\n<p>Inaccurate time keeping can result in system instability. Test any change to the clock source very carefully. Operating system defaults are sometimes made to favor reliability over best accuracy. And if you are using a virtual machine, look into the recommended time sources compatible with it. Virtual hardware faces additional difficulties when emulating timers, and there are often per operating system settings suggested by vendors.</p>\n<p>The Time Stamp Counter (TSC) clock source is the most accurate one available on current generation CPUs. It's the preferred way to track the system time when it's supported by the operating system and the TSC clock is reliable. There are several ways that TSC can fail to provide an accurate timing source, making it unreliable. Older systems can have a TSC clock that varies based on the CPU temperature, making it unusable for timing. Trying to use TSC on some older multicore CPUs can give a reported time that's inconsistent among multiple cores. This can result in the time going backwards, a problem this program checks for. And even the newest systems can fail to provide accurate TSC timing with very aggressive power saving configurations.</p>\n<p>Newer operating systems may check for the known TSC problems and switch to a slower, more stable clock source when they are seen. If your system supports TSC time but doesn't default to that, it may be disabled for a good reason. And some operating systems may not detect all the possible problems correctly, or will allow using TSC even in situations where it's known to be inaccurate.</p>\n<p>The High Precision Event Timer (HPET) is the preferred timer on systems where it's available and TSC is not accurate. The timer chip itself is programmable to allow up to 100 nanosecond resolution, but you may not see that much accuracy in your system clock.</p>\n<p>Advanced Configuration and Power Interface (ACPI) provides a Power Management (PM) Timer, which Linux refers to as the acpi_pm. The clock derived from acpi_pm will at best provide 300 nanosecond resolution.</p>\n<p>Timers used on older PC hardware include the 8254 Programmable Interval Timer (PIT), the real-time clock (RTC), the Advanced Programmable Interrupt Controller (APIC) timer, and the Cyclone timer. These timers aim for millisecond resolution.</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.10.8\">\n<h2>See Also</h2><span class=\"simplelist\"><a class=\"xref\" href=\"/docs/11/sql-explain.html\" title=\"EXPLAIN\"><span class=\"refentrytitle\">EXPLAIN</span></a></span>\n</div>\n</div></div>", "manual_path": "pgtesttiming.html", "comparison_data": {"options": [{"names": ["-d duration", "--duration= duration"], "signature": "-d duration --duration= duration", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "signature": "-V --version", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "signature": "-? --help", "description": "Show help about pg_test_timing command line arguments, and exit."}], "synopsis": ["pg_test_timing [ option ...]"], "environment": []}, "comparison_hash": "1e9850049374c38671166c0a5cf0759d6f33dd01f733985211c9962ac16213b4"}, "12": {"facts": [{"label": "Documented executable", "value": "pg_test_timing"}, {"label": "Executable version", "value": "12.22"}, {"label": "Reference inventory", "value": "Server applications"}, {"label": "Option definition groups", "value": "3"}], "tables": [{"key": "options", "rows": [{"summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": {"url": "/docs/12/pgtesttiming.html", "text": "-d duration --duration= duration"}}, {"summary": "Print the pg_test_timing version and exit.", "signature": {"url": "/docs/12/pgtesttiming.html", "text": "-V --version"}}, {"summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": {"url": "/docs/12/pgtesttiming.html", "text": "-? --help"}}], "title": "Documented options", "columns": [{"key": "signature", "label": "Option and arguments"}, {"key": "summary", "label": "Description"}]}], "options": [{"names": ["-d duration", "--duration= duration"], "summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": "-d duration --duration= duration", "source_url": "/docs/12/pgtesttiming.html", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "summary": "Print the pg_test_timing version and exit.", "signature": "-V --version", "source_url": "/docs/12/pgtesttiming.html", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": "-? --help", "source_url": "/docs/12/pgtesttiming.html", "description": "Show help about pg_test_timing command line arguments, and exit."}], "related": [], "release": {"ref": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "label": "12.22", "major": "12", "channel": "historical", "manifest": {"pdf": {"A4": {"url": "/files/documentation/pdf/12/postgresql-12-A4.pdf", "bytes": 13424351, "pages": 2803, "sha256": "7422cf53fd1939e7a3d2925231a88b0330e468afa5393627cac0ff86158a0621", "built_at": "2026-09-26"}, "US": {"url": "/files/documentation/pdf/12/postgresql-12-US.pdf", "bytes": 13322565, "pages": 2958, "sha256": "51f3b04e72907fc38512685946223452ea65f84419c60c66241dfa3396035e77", "built_at": "2026-09-26"}}, "tree": "12", "index": "index.html", "major": "12", "pages": 1131, "release": "12.22", "source_url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "svg_assets": 2, "source_mode": "en HTML verified against the pinned official archive", "source_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}, "revision": "7a827e97cbfacd7febff75f34443e2043e40723de5b6d8c9d81a9430b65a37e4", "evidence_kind": "English manual and source declarations", "source_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}, "sources": [{"url": "/docs/12/pgtesttiming.html", "file": "pgtesttiming.html", "label": "12.22 English manual \u00b7 pgtesttiming.html", "anchor": "", "sha256": "2c710bb79864e47c2a5ed343e2881495934b38398ac8bc7280803ce8c2b863c9"}, {"url": "/docs/12/reference-server.html", "file": "reference-server.html", "label": "Server applications inventory", "anchor": "", "sha256": "7f6ae1fadc1b0bffa606551460e62aacdc2508a3fb66566ddae861928ca6080b"}], "sections": [], "synopsis": ["pg_test_timing [ option ...]"], "signature": "pg_test_timing [ option ...]", "description": ["pg_test_timing \u2014 measure timing overhead"], "environment": [], "manual_html": "<div><div class=\"refentry\" id=\"PGTESTTIMING\">\n<div class=\"titlepage\"></div>\n<div class=\"refnamediv\">\n<h2><span class=\"refentrytitle\"><span class=\"application\">pg_test_timing</span></span></h2>\n<p>pg_test_timing \u2014 measure timing overhead</p>\n</div>\n<div class=\"refsynopsisdiv\">\n<h2>Synopsis</h2>\n<div class=\"cmdsynopsis\">\n<p id=\"id-1.9.5.11.4.1\"><code class=\"command\">pg_test_timing</code> [<em class=\"replaceable\"><code>option</code></em>...]</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.5\">\n<h2>Description</h2>\n<p><span class=\"application\">pg_test_timing</span> is a tool to measure the timing overhead on your system and confirm that the system time never moves backwards. Systems that are slow to collect timing data can give less accurate <code class=\"command\">EXPLAIN ANALYZE</code> results.</p>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.6\">\n<h2>Options</h2>\n<p><span class=\"application\">pg_test_timing</span> accepts the following command-line options:</p>\n<div class=\"variablelist\">\n<dl class=\"variablelist\">\n<dt><span class=\"term\"><code class=\"option\">-d <em class=\"replaceable\"><code>duration</code></em></code><br></span><span class=\"term\"><code class=\"option\">--duration=<em class=\"replaceable\"><code>duration</code></em></code></span></dt>\n<dd>\n<p>Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-V</code><br></span><span class=\"term\"><code class=\"option\">--version</code></span></dt>\n<dd>\n<p>Print the <span class=\"application\">pg_test_timing</span> version and exit.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-?</code><br></span><span class=\"term\"><code class=\"option\">--help</code></span></dt>\n<dd>\n<p>Show help about <span class=\"application\">pg_test_timing</span> command line arguments, and exit.</p>\n</dd>\n</dl>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.7\">\n<h2>Usage</h2>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.2\">\n<h3>Interpreting Results</h3>\n<p>Good results will show most (&gt;90%) individual timing calls take less than one microsecond. Average per loop overhead will be even lower, below 100 nanoseconds. This example from an Intel i7-860 system using a TSC clock source shows excellent performance:</p>\n<pre class=\"screen\">Testing timing overhead for 3 seconds.\nPer loop time including overhead: 35.96 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     96.40465   80435604\n     2      3.59518    2999652\n     4      0.00015        126\n     8      0.00002         13\n    16      0.00000          2\n</pre>\n<p>Note that different units are used for the per loop time than the histogram. The loop can have resolution within a few nanoseconds (ns), while the individual timing calls can only resolve down to one microsecond (us).</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.3\">\n<h3>Measuring Executor Timing Overhead</h3>\n<p>When the query executor is running a statement using <code class=\"command\">EXPLAIN ANALYZE</code>, individual operations are timed as well as showing a summary. The overhead of your system can be checked by counting rows with the <span class=\"application\">psql</span> program:</p>\n<pre class=\"screen\">CREATE TABLE t AS SELECT * FROM generate_series(1,100000);\n\\timing\nSELECT COUNT(*) FROM t;\nEXPLAIN ANALYZE SELECT COUNT(*) FROM t;\n</pre>\n<p>The i7-860 system measured runs the count query in 9.8 ms while the <code class=\"command\">EXPLAIN ANALYZE</code> version takes 16.6 ms, each processing just over 100,000 rows. That 6.8 ms difference means the timing overhead per row is 68 ns, about twice what pg_test_timing estimated it would be. Even that relatively small amount of overhead is making the fully timed count statement take almost 70% longer. On more substantial queries, the timing overhead would be less problematic.</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.4\">\n<h3>Changing Time Sources</h3>\n<p>On some newer Linux systems, it's possible to change the clock source used to collect timing data at any time. A second example shows the slowdown possible from switching to the slower acpi_pm time source, on the same system used for the fast results above:</p>\n<pre class=\"screen\"># cat /sys/devices/system/clocksource/clocksource0/available_clocksource\ntsc hpet acpi_pm\n# echo acpi_pm &gt; /sys/devices/system/clocksource/clocksource0/current_clocksource\n# pg_test_timing\nPer loop time including overhead: 722.92 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     27.84870    1155682\n     2     72.05956    2990371\n     4      0.07810       3241\n     8      0.01357        563\n    16      0.00007          3\n</pre>\n<p>In this configuration, the sample <code class=\"command\">EXPLAIN ANALYZE</code> above takes 115.9 ms. That's 1061 ns of timing overhead, again a small multiple of what's measured directly by this utility. That much timing overhead means the actual query itself is only taking a tiny fraction of the accounted for time, most of it is being consumed in overhead instead. In this configuration, any <code class=\"command\">EXPLAIN ANALYZE</code> totals involving many timed operations would be inflated significantly by timing overhead.</p>\n<p>FreeBSD also allows changing the time source on the fly, and it logs information about the timer selected during boot:</p>\n<pre class=\"screen\"># dmesg | grep \"Timecounter\"\nTimecounter \"ACPI-fast\" frequency 3579545 Hz quality 900\nTimecounter \"i8254\" frequency 1193182 Hz quality 0\nTimecounters tick every 10.000 msec\nTimecounter \"TSC\" frequency 2531787134 Hz quality 800\n# sysctl kern.timecounter.hardware=TSC\nkern.timecounter.hardware: ACPI-fast -&gt; TSC\n</pre>\n<p>Other systems may only allow setting the time source on boot. On older Linux systems the \"clock\" kernel setting is the only way to make this sort of change. And even on some more recent ones, the only option you'll see for a clock source is \"jiffies\". Jiffies are the older Linux software clock implementation, which can have good resolution when it's backed by fast enough timing hardware, as in this example:</p>\n<pre class=\"screen\">$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource\njiffies\n$ dmesg | grep time.c\ntime.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.\ntime.c: Detected 2400.153 MHz processor.\n$ pg_test_timing\nTesting timing overhead for 3 seconds.\nPer timing duration including loop overhead: 97.75 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     90.23734   27694571\n     2      9.75277    2993204\n     4      0.00981       3010\n     8      0.00007         22\n    16      0.00000          1\n    32      0.00000          1\n</pre>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.5\">\n<h3>Clock Hardware and Timing Accuracy</h3>\n<p>Collecting accurate timing information is normally done on computers using hardware clocks with various levels of accuracy. With some hardware the operating systems can pass the system clock time almost directly to programs. A system clock can also be derived from a chip that simply provides timing interrupts, periodic ticks at some known time interval. In either case, operating system kernels provide a clock source that hides these details. But the accuracy of that clock source and how quickly it can return results varies based on the underlying hardware.</p>\n<p>Inaccurate time keeping can result in system instability. Test any change to the clock source very carefully. Operating system defaults are sometimes made to favor reliability over best accuracy. And if you are using a virtual machine, look into the recommended time sources compatible with it. Virtual hardware faces additional difficulties when emulating timers, and there are often per operating system settings suggested by vendors.</p>\n<p>The Time Stamp Counter (TSC) clock source is the most accurate one available on current generation CPUs. It's the preferred way to track the system time when it's supported by the operating system and the TSC clock is reliable. There are several ways that TSC can fail to provide an accurate timing source, making it unreliable. Older systems can have a TSC clock that varies based on the CPU temperature, making it unusable for timing. Trying to use TSC on some older multicore CPUs can give a reported time that's inconsistent among multiple cores. This can result in the time going backwards, a problem this program checks for. And even the newest systems can fail to provide accurate TSC timing with very aggressive power saving configurations.</p>\n<p>Newer operating systems may check for the known TSC problems and switch to a slower, more stable clock source when they are seen. If your system supports TSC time but doesn't default to that, it may be disabled for a good reason. And some operating systems may not detect all the possible problems correctly, or will allow using TSC even in situations where it's known to be inaccurate.</p>\n<p>The High Precision Event Timer (HPET) is the preferred timer on systems where it's available and TSC is not accurate. The timer chip itself is programmable to allow up to 100 nanosecond resolution, but you may not see that much accuracy in your system clock.</p>\n<p>Advanced Configuration and Power Interface (ACPI) provides a Power Management (PM) Timer, which Linux refers to as the acpi_pm. The clock derived from acpi_pm will at best provide 300 nanosecond resolution.</p>\n<p>Timers used on older PC hardware include the 8254 Programmable Interval Timer (PIT), the real-time clock (RTC), the Advanced Programmable Interrupt Controller (APIC) timer, and the Cyclone timer. These timers aim for millisecond resolution.</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.8\">\n<h2>See Also</h2><span class=\"simplelist\"><a class=\"xref\" href=\"/docs/12/sql-explain.html\" title=\"EXPLAIN\"><span class=\"refentrytitle\">EXPLAIN</span></a></span>\n</div>\n</div></div>", "manual_path": "pgtesttiming.html", "comparison_data": {"options": [{"names": ["-d duration", "--duration= duration"], "signature": "-d duration --duration= duration", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "signature": "-V --version", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "signature": "-? --help", "description": "Show help about pg_test_timing command line arguments, and exit."}], "synopsis": ["pg_test_timing [ option ...]"], "environment": []}, "comparison_hash": "1e9850049374c38671166c0a5cf0759d6f33dd01f733985211c9962ac16213b4"}, "13": {"facts": [{"label": "Documented executable", "value": "pg_test_timing"}, {"label": "Executable version", "value": "13.23"}, {"label": "Reference inventory", "value": "Server applications"}, {"label": "Option definition groups", "value": "3"}], "tables": [{"key": "options", "rows": [{"summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": {"url": "/docs/13/pgtesttiming.html", "text": "-d duration --duration= duration"}}, {"summary": "Print the pg_test_timing version and exit.", "signature": {"url": "/docs/13/pgtesttiming.html", "text": "-V --version"}}, {"summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": {"url": "/docs/13/pgtesttiming.html", "text": "-? --help"}}], "title": "Documented options", "columns": [{"key": "signature", "label": "Option and arguments"}, {"key": "summary", "label": "Description"}]}], "options": [{"names": ["-d duration", "--duration= duration"], "summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": "-d duration --duration= duration", "source_url": "/docs/13/pgtesttiming.html", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "summary": "Print the pg_test_timing version and exit.", "signature": "-V --version", "source_url": "/docs/13/pgtesttiming.html", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": "-? --help", "source_url": "/docs/13/pgtesttiming.html", "description": "Show help about pg_test_timing command line arguments, and exit."}], "related": [], "release": {"ref": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "label": "13.23", "major": "13", "channel": "historical", "manifest": {"pdf": {"A4": {"url": "/files/documentation/pdf/13/postgresql-13-A4.pdf", "bytes": 13843239, "pages": 2826, "sha256": "171cc09f90936dbc1cbd503a98ff07ae72ea58ab9771ff051313f1217737799c", "built_at": "2026-09-26"}, "US": {"url": "/files/documentation/pdf/13/postgresql-13-US.pdf", "bytes": 13739572, "pages": 2984, "sha256": "48d09c6e197d9db4220f41afe83efe848a8661b1b168d3b89419751ecaf6c24d", "built_at": "2026-09-26"}}, "tree": "13", "index": "index.html", "major": "13", "pages": 1139, "release": "13.23", "source_url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "svg_assets": 3, "source_mode": "en HTML verified against the pinned official archive", "source_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}, "revision": "614ee3133270254e476c118cdf6f72af78d4e4b8bbd9b28ed9ab1e14e4e9c0f6", "evidence_kind": "English manual and source declarations", "source_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}, "sources": [{"url": "/docs/13/pgtesttiming.html", "file": "pgtesttiming.html", "label": "13.23 English manual \u00b7 pgtesttiming.html", "anchor": "", "sha256": "b207d5aa4db462ca33bfe7d1dd13bbb86b654fccb220fe58293c4e842c1bf1b9"}, {"url": "/docs/13/reference-server.html", "file": "reference-server.html", "label": "Server applications inventory", "anchor": "", "sha256": "074ef8577fd368272a2360309e1226e2d0b1e570a3e1da62dfcca63ac9ee5539"}], "sections": [], "synopsis": ["pg_test_timing [ option ...]"], "signature": "pg_test_timing [ option ...]", "description": ["pg_test_timing \u2014 measure timing overhead"], "environment": [], "manual_html": "<div><div class=\"refentry\" id=\"PGTESTTIMING\">\n<div class=\"titlepage\"></div>\n<div class=\"refnamediv\">\n<h2><span class=\"refentrytitle\"><span class=\"application\">pg_test_timing</span></span></h2>\n<p>pg_test_timing \u2014 measure timing overhead</p>\n</div>\n<div class=\"refsynopsisdiv\">\n<h2>Synopsis</h2>\n<div class=\"cmdsynopsis\">\n<p id=\"id-1.9.5.11.4.1\"><code class=\"command\">pg_test_timing</code> [<em class=\"replaceable\"><code>option</code></em>...]</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.5\">\n<h2>Description</h2>\n<p><span class=\"application\">pg_test_timing</span> is a tool to measure the timing overhead on your system and confirm that the system time never moves backwards. Systems that are slow to collect timing data can give less accurate <code class=\"command\">EXPLAIN ANALYZE</code> results.</p>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.6\">\n<h2>Options</h2>\n<p><span class=\"application\">pg_test_timing</span> accepts the following command-line options:</p>\n<div class=\"variablelist\">\n<dl class=\"variablelist\">\n<dt><span class=\"term\"><code class=\"option\">-d <em class=\"replaceable\"><code>duration</code></em></code><br></span><span class=\"term\"><code class=\"option\">--duration=<em class=\"replaceable\"><code>duration</code></em></code></span></dt>\n<dd>\n<p>Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-V</code><br></span><span class=\"term\"><code class=\"option\">--version</code></span></dt>\n<dd>\n<p>Print the <span class=\"application\">pg_test_timing</span> version and exit.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-?</code><br></span><span class=\"term\"><code class=\"option\">--help</code></span></dt>\n<dd>\n<p>Show help about <span class=\"application\">pg_test_timing</span> command line arguments, and exit.</p>\n</dd>\n</dl>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.7\">\n<h2>Usage</h2>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.2\">\n<h3>Interpreting Results</h3>\n<p>Good results will show most (&gt;90%) individual timing calls take less than one microsecond. Average per loop overhead will be even lower, below 100 nanoseconds. This example from an Intel i7-860 system using a TSC clock source shows excellent performance:</p>\n<pre class=\"screen\">Testing timing overhead for 3 seconds.\nPer loop time including overhead: 35.96 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     96.40465   80435604\n     2      3.59518    2999652\n     4      0.00015        126\n     8      0.00002         13\n    16      0.00000          2\n</pre>\n<p>Note that different units are used for the per loop time than the histogram. The loop can have resolution within a few nanoseconds (ns), while the individual timing calls can only resolve down to one microsecond (us).</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.3\">\n<h3>Measuring Executor Timing Overhead</h3>\n<p>When the query executor is running a statement using <code class=\"command\">EXPLAIN ANALYZE</code>, individual operations are timed as well as showing a summary. The overhead of your system can be checked by counting rows with the <span class=\"application\">psql</span> program:</p>\n<pre class=\"screen\">CREATE TABLE t AS SELECT * FROM generate_series(1,100000);\n\\timing\nSELECT COUNT(*) FROM t;\nEXPLAIN ANALYZE SELECT COUNT(*) FROM t;\n</pre>\n<p>The i7-860 system measured runs the count query in 9.8 ms while the <code class=\"command\">EXPLAIN ANALYZE</code> version takes 16.6 ms, each processing just over 100,000 rows. That 6.8 ms difference means the timing overhead per row is 68 ns, about twice what pg_test_timing estimated it would be. Even that relatively small amount of overhead is making the fully timed count statement take almost 70% longer. On more substantial queries, the timing overhead would be less problematic.</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.4\">\n<h3>Changing Time Sources</h3>\n<p>On some newer Linux systems, it's possible to change the clock source used to collect timing data at any time. A second example shows the slowdown possible from switching to the slower acpi_pm time source, on the same system used for the fast results above:</p>\n<pre class=\"screen\"># cat /sys/devices/system/clocksource/clocksource0/available_clocksource\ntsc hpet acpi_pm\n# echo acpi_pm &gt; /sys/devices/system/clocksource/clocksource0/current_clocksource\n# pg_test_timing\nPer loop time including overhead: 722.92 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     27.84870    1155682\n     2     72.05956    2990371\n     4      0.07810       3241\n     8      0.01357        563\n    16      0.00007          3\n</pre>\n<p>In this configuration, the sample <code class=\"command\">EXPLAIN ANALYZE</code> above takes 115.9 ms. That's 1061 ns of timing overhead, again a small multiple of what's measured directly by this utility. That much timing overhead means the actual query itself is only taking a tiny fraction of the accounted for time, most of it is being consumed in overhead instead. In this configuration, any <code class=\"command\">EXPLAIN ANALYZE</code> totals involving many timed operations would be inflated significantly by timing overhead.</p>\n<p>FreeBSD also allows changing the time source on the fly, and it logs information about the timer selected during boot:</p>\n<pre class=\"screen\"># dmesg | grep \"Timecounter\"\nTimecounter \"ACPI-fast\" frequency 3579545 Hz quality 900\nTimecounter \"i8254\" frequency 1193182 Hz quality 0\nTimecounters tick every 10.000 msec\nTimecounter \"TSC\" frequency 2531787134 Hz quality 800\n# sysctl kern.timecounter.hardware=TSC\nkern.timecounter.hardware: ACPI-fast -&gt; TSC\n</pre>\n<p>Other systems may only allow setting the time source on boot. On older Linux systems the \"clock\" kernel setting is the only way to make this sort of change. And even on some more recent ones, the only option you'll see for a clock source is \"jiffies\". Jiffies are the older Linux software clock implementation, which can have good resolution when it's backed by fast enough timing hardware, as in this example:</p>\n<pre class=\"screen\">$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource\njiffies\n$ dmesg | grep time.c\ntime.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.\ntime.c: Detected 2400.153 MHz processor.\n$ pg_test_timing\nTesting timing overhead for 3 seconds.\nPer timing duration including loop overhead: 97.75 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     90.23734   27694571\n     2      9.75277    2993204\n     4      0.00981       3010\n     8      0.00007         22\n    16      0.00000          1\n    32      0.00000          1\n</pre>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.5\">\n<h3>Clock Hardware and Timing Accuracy</h3>\n<p>Collecting accurate timing information is normally done on computers using hardware clocks with various levels of accuracy. With some hardware the operating systems can pass the system clock time almost directly to programs. A system clock can also be derived from a chip that simply provides timing interrupts, periodic ticks at some known time interval. In either case, operating system kernels provide a clock source that hides these details. But the accuracy of that clock source and how quickly it can return results varies based on the underlying hardware.</p>\n<p>Inaccurate time keeping can result in system instability. Test any change to the clock source very carefully. Operating system defaults are sometimes made to favor reliability over best accuracy. And if you are using a virtual machine, look into the recommended time sources compatible with it. Virtual hardware faces additional difficulties when emulating timers, and there are often per operating system settings suggested by vendors.</p>\n<p>The Time Stamp Counter (TSC) clock source is the most accurate one available on current generation CPUs. It's the preferred way to track the system time when it's supported by the operating system and the TSC clock is reliable. There are several ways that TSC can fail to provide an accurate timing source, making it unreliable. Older systems can have a TSC clock that varies based on the CPU temperature, making it unusable for timing. Trying to use TSC on some older multicore CPUs can give a reported time that's inconsistent among multiple cores. This can result in the time going backwards, a problem this program checks for. And even the newest systems can fail to provide accurate TSC timing with very aggressive power saving configurations.</p>\n<p>Newer operating systems may check for the known TSC problems and switch to a slower, more stable clock source when they are seen. If your system supports TSC time but doesn't default to that, it may be disabled for a good reason. And some operating systems may not detect all the possible problems correctly, or will allow using TSC even in situations where it's known to be inaccurate.</p>\n<p>The High Precision Event Timer (HPET) is the preferred timer on systems where it's available and TSC is not accurate. The timer chip itself is programmable to allow up to 100 nanosecond resolution, but you may not see that much accuracy in your system clock.</p>\n<p>Advanced Configuration and Power Interface (ACPI) provides a Power Management (PM) Timer, which Linux refers to as the acpi_pm. The clock derived from acpi_pm will at best provide 300 nanosecond resolution.</p>\n<p>Timers used on older PC hardware include the 8254 Programmable Interval Timer (PIT), the real-time clock (RTC), the Advanced Programmable Interrupt Controller (APIC) timer, and the Cyclone timer. These timers aim for millisecond resolution.</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.8\">\n<h2>See Also</h2><span class=\"simplelist\"><a class=\"xref\" href=\"/docs/13/sql-explain.html\" title=\"EXPLAIN\"><span class=\"refentrytitle\">EXPLAIN</span></a></span>\n</div>\n</div></div>", "manual_path": "pgtesttiming.html", "comparison_data": {"options": [{"names": ["-d duration", "--duration= duration"], "signature": "-d duration --duration= duration", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "signature": "-V --version", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "signature": "-? --help", "description": "Show help about pg_test_timing command line arguments, and exit."}], "synopsis": ["pg_test_timing [ option ...]"], "environment": []}, "comparison_hash": "1e9850049374c38671166c0a5cf0759d6f33dd01f733985211c9962ac16213b4"}, "14": {"facts": [{"label": "Documented executable", "value": "pg_test_timing"}, {"label": "Executable version", "value": "14.24"}, {"label": "Reference inventory", "value": "Server applications"}, {"label": "Option definition groups", "value": "3"}], "tables": [{"key": "options", "rows": [{"summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": {"url": "/docs/14/pgtesttiming.html", "text": "-d duration --duration= duration"}}, {"summary": "Print the pg_test_timing version and exit.", "signature": {"url": "/docs/14/pgtesttiming.html", "text": "-V --version"}}, {"summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": {"url": "/docs/14/pgtesttiming.html", "text": "-? --help"}}], "title": "Documented options", "columns": [{"key": "signature", "label": "Option and arguments"}, {"key": "summary", "label": "Description"}]}], "options": [{"names": ["-d duration", "--duration= duration"], "summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": "-d duration --duration= duration", "source_url": "/docs/14/pgtesttiming.html", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "summary": "Print the pg_test_timing version and exit.", "signature": "-V --version", "source_url": "/docs/14/pgtesttiming.html", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": "-? --help", "source_url": "/docs/14/pgtesttiming.html", "description": "Show help about pg_test_timing command line arguments, and exit."}], "related": [], "release": {"ref": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "label": "14.24", "major": "14", "channel": "stable", "manifest": {"pdf": {"A4": {"url": "/files/documentation/pdf/14/postgresql-14-A4.pdf", "bytes": 14354704, "pages": 2944, "sha256": "8bc6b9dd7b246888bb77f0a5e8c39a2eae52e9926569832669c7d1600becb27c", "built_at": "2026-09-26"}, "US": {"url": "/files/documentation/pdf/14/postgresql-14-US.pdf", "bytes": 14242178, "pages": 3102, "sha256": "b7ecb5a5f62d8b9f73a69e25a7d26ba285373bc53168a553bff7b77955506db4", "built_at": "2026-09-26"}}, "tree": "14", "index": "index.html", "major": "14", "pages": 1158, "release": "14.24", "source_url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "svg_assets": 3, "source_mode": "en HTML verified against the pinned official archive", "source_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}, "revision": "588700d46356d8837c77c7c0a4e71e645fe6535983b8f1830aa8f2e4e41c40ae", "evidence_kind": "English manual and source declarations", "source_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}, "sources": [{"url": "/docs/14/pgtesttiming.html", "file": "pgtesttiming.html", "label": "14.24 English manual \u00b7 pgtesttiming.html", "anchor": "", "sha256": "774f0ff3c73a42d06b79d09f42f68482decbad88c1c68c4ace0adcfdda679555"}, {"url": "/docs/14/reference-server.html", "file": "reference-server.html", "label": "Server applications inventory", "anchor": "", "sha256": "db0cdccaa8d3c65ad3b2a07d4956eb5a783a18505bfa0f9d9626eef4ab94fe44"}], "sections": [], "synopsis": ["pg_test_timing [ option ...]"], "signature": "pg_test_timing [ option ...]", "description": ["pg_test_timing \u2014 measure timing overhead"], "environment": [], "manual_html": "<div><div class=\"refentry\" id=\"PGTESTTIMING\">\n<div class=\"titlepage\"></div>\n<div class=\"refnamediv\">\n<h2><span class=\"refentrytitle\"><span class=\"application\">pg_test_timing</span></span></h2>\n<p>pg_test_timing \u2014 measure timing overhead</p>\n</div>\n<div class=\"refsynopsisdiv\">\n<h2>Synopsis</h2>\n<div class=\"cmdsynopsis\">\n<p id=\"id-1.9.5.11.4.1\"><code class=\"command\">pg_test_timing</code> [<em class=\"replaceable\"><code>option</code></em>...]</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.5\">\n<h2>Description</h2>\n<p><span class=\"application\">pg_test_timing</span> is a tool to measure the timing overhead on your system and confirm that the system time never moves backwards. Systems that are slow to collect timing data can give less accurate <code class=\"command\">EXPLAIN ANALYZE</code> results.</p>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.6\">\n<h2>Options</h2>\n<p><span class=\"application\">pg_test_timing</span> accepts the following command-line options:</p>\n<div class=\"variablelist\">\n<dl class=\"variablelist\">\n<dt><span class=\"term\"><code class=\"option\">-d <em class=\"replaceable\"><code>duration</code></em></code><br></span><span class=\"term\"><code class=\"option\">--duration=<em class=\"replaceable\"><code>duration</code></em></code></span></dt>\n<dd>\n<p>Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-V</code><br></span><span class=\"term\"><code class=\"option\">--version</code></span></dt>\n<dd>\n<p>Print the <span class=\"application\">pg_test_timing</span> version and exit.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-?</code><br></span><span class=\"term\"><code class=\"option\">--help</code></span></dt>\n<dd>\n<p>Show help about <span class=\"application\">pg_test_timing</span> command line arguments, and exit.</p>\n</dd>\n</dl>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.7\">\n<h2>Usage</h2>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.2\">\n<h3>Interpreting Results</h3>\n<p>Good results will show most (&gt;90%) individual timing calls take less than one microsecond. Average per loop overhead will be even lower, below 100 nanoseconds. This example from an Intel i7-860 system using a TSC clock source shows excellent performance:</p>\n<pre class=\"screen\">Testing timing overhead for 3 seconds.\nPer loop time including overhead: 35.96 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     96.40465   80435604\n     2      3.59518    2999652\n     4      0.00015        126\n     8      0.00002         13\n    16      0.00000          2\n</pre>\n<p>Note that different units are used for the per loop time than the histogram. The loop can have resolution within a few nanoseconds (ns), while the individual timing calls can only resolve down to one microsecond (us).</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.3\">\n<h3>Measuring Executor Timing Overhead</h3>\n<p>When the query executor is running a statement using <code class=\"command\">EXPLAIN ANALYZE</code>, individual operations are timed as well as showing a summary. The overhead of your system can be checked by counting rows with the <span class=\"application\">psql</span> program:</p>\n<pre class=\"screen\">CREATE TABLE t AS SELECT * FROM generate_series(1,100000);\n\\timing\nSELECT COUNT(*) FROM t;\nEXPLAIN ANALYZE SELECT COUNT(*) FROM t;\n</pre>\n<p>The i7-860 system measured runs the count query in 9.8 ms while the <code class=\"command\">EXPLAIN ANALYZE</code> version takes 16.6 ms, each processing just over 100,000 rows. That 6.8 ms difference means the timing overhead per row is 68 ns, about twice what pg_test_timing estimated it would be. Even that relatively small amount of overhead is making the fully timed count statement take almost 70% longer. On more substantial queries, the timing overhead would be less problematic.</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.4\">\n<h3>Changing Time Sources</h3>\n<p>On some newer Linux systems, it's possible to change the clock source used to collect timing data at any time. A second example shows the slowdown possible from switching to the slower acpi_pm time source, on the same system used for the fast results above:</p>\n<pre class=\"screen\"># cat /sys/devices/system/clocksource/clocksource0/available_clocksource\ntsc hpet acpi_pm\n# echo acpi_pm &gt; /sys/devices/system/clocksource/clocksource0/current_clocksource\n# pg_test_timing\nPer loop time including overhead: 722.92 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     27.84870    1155682\n     2     72.05956    2990371\n     4      0.07810       3241\n     8      0.01357        563\n    16      0.00007          3\n</pre>\n<p>In this configuration, the sample <code class=\"command\">EXPLAIN ANALYZE</code> above takes 115.9 ms. That's 1061 ns of timing overhead, again a small multiple of what's measured directly by this utility. That much timing overhead means the actual query itself is only taking a tiny fraction of the accounted for time, most of it is being consumed in overhead instead. In this configuration, any <code class=\"command\">EXPLAIN ANALYZE</code> totals involving many timed operations would be inflated significantly by timing overhead.</p>\n<p>FreeBSD also allows changing the time source on the fly, and it logs information about the timer selected during boot:</p>\n<pre class=\"screen\"># dmesg | grep \"Timecounter\"\nTimecounter \"ACPI-fast\" frequency 3579545 Hz quality 900\nTimecounter \"i8254\" frequency 1193182 Hz quality 0\nTimecounters tick every 10.000 msec\nTimecounter \"TSC\" frequency 2531787134 Hz quality 800\n# sysctl kern.timecounter.hardware=TSC\nkern.timecounter.hardware: ACPI-fast -&gt; TSC\n</pre>\n<p>Other systems may only allow setting the time source on boot. On older Linux systems the \"clock\" kernel setting is the only way to make this sort of change. And even on some more recent ones, the only option you'll see for a clock source is \"jiffies\". Jiffies are the older Linux software clock implementation, which can have good resolution when it's backed by fast enough timing hardware, as in this example:</p>\n<pre class=\"screen\">$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource\njiffies\n$ dmesg | grep time.c\ntime.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.\ntime.c: Detected 2400.153 MHz processor.\n$ pg_test_timing\nTesting timing overhead for 3 seconds.\nPer timing duration including loop overhead: 97.75 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     90.23734   27694571\n     2      9.75277    2993204\n     4      0.00981       3010\n     8      0.00007         22\n    16      0.00000          1\n    32      0.00000          1\n</pre>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.5\">\n<h3>Clock Hardware and Timing Accuracy</h3>\n<p>Collecting accurate timing information is normally done on computers using hardware clocks with various levels of accuracy. With some hardware the operating systems can pass the system clock time almost directly to programs. A system clock can also be derived from a chip that simply provides timing interrupts, periodic ticks at some known time interval. In either case, operating system kernels provide a clock source that hides these details. But the accuracy of that clock source and how quickly it can return results varies based on the underlying hardware.</p>\n<p>Inaccurate time keeping can result in system instability. Test any change to the clock source very carefully. Operating system defaults are sometimes made to favor reliability over best accuracy. And if you are using a virtual machine, look into the recommended time sources compatible with it. Virtual hardware faces additional difficulties when emulating timers, and there are often per operating system settings suggested by vendors.</p>\n<p>The Time Stamp Counter (TSC) clock source is the most accurate one available on current generation CPUs. It's the preferred way to track the system time when it's supported by the operating system and the TSC clock is reliable. There are several ways that TSC can fail to provide an accurate timing source, making it unreliable. Older systems can have a TSC clock that varies based on the CPU temperature, making it unusable for timing. Trying to use TSC on some older multicore CPUs can give a reported time that's inconsistent among multiple cores. This can result in the time going backwards, a problem this program checks for. And even the newest systems can fail to provide accurate TSC timing with very aggressive power saving configurations.</p>\n<p>Newer operating systems may check for the known TSC problems and switch to a slower, more stable clock source when they are seen. If your system supports TSC time but doesn't default to that, it may be disabled for a good reason. And some operating systems may not detect all the possible problems correctly, or will allow using TSC even in situations where it's known to be inaccurate.</p>\n<p>The High Precision Event Timer (HPET) is the preferred timer on systems where it's available and TSC is not accurate. The timer chip itself is programmable to allow up to 100 nanosecond resolution, but you may not see that much accuracy in your system clock.</p>\n<p>Advanced Configuration and Power Interface (ACPI) provides a Power Management (PM) Timer, which Linux refers to as the acpi_pm. The clock derived from acpi_pm will at best provide 300 nanosecond resolution.</p>\n<p>Timers used on older PC hardware include the 8254 Programmable Interval Timer (PIT), the real-time clock (RTC), the Advanced Programmable Interrupt Controller (APIC) timer, and the Cyclone timer. These timers aim for millisecond resolution.</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.8\">\n<h2>See Also</h2><span class=\"simplelist\"><a class=\"xref\" href=\"/docs/14/sql-explain.html\" title=\"EXPLAIN\"><span class=\"refentrytitle\">EXPLAIN</span></a></span>\n</div>\n</div></div>", "manual_path": "pgtesttiming.html", "comparison_data": {"options": [{"names": ["-d duration", "--duration= duration"], "signature": "-d duration --duration= duration", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "signature": "-V --version", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "signature": "-? --help", "description": "Show help about pg_test_timing command line arguments, and exit."}], "synopsis": ["pg_test_timing [ option ...]"], "environment": []}, "comparison_hash": "1e9850049374c38671166c0a5cf0759d6f33dd01f733985211c9962ac16213b4"}, "15": {"facts": [{"label": "Documented executable", "value": "pg_test_timing"}, {"label": "Executable version", "value": "15.19"}, {"label": "Reference inventory", "value": "Server applications"}, {"label": "Option definition groups", "value": "3"}], "tables": [{"key": "options", "rows": [{"summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": {"url": "/docs/15/pgtesttiming.html", "text": "-d duration --duration= duration"}}, {"summary": "Print the pg_test_timing version and exit.", "signature": {"url": "/docs/15/pgtesttiming.html", "text": "-V --version"}}, {"summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": {"url": "/docs/15/pgtesttiming.html", "text": "-? --help"}}], "title": "Documented options", "columns": [{"key": "signature", "label": "Option and arguments"}, {"key": "summary", "label": "Description"}]}], "options": [{"names": ["-d duration", "--duration= duration"], "summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": "-d duration --duration= duration", "source_url": "/docs/15/pgtesttiming.html", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "summary": "Print the pg_test_timing version and exit.", "signature": "-V --version", "source_url": "/docs/15/pgtesttiming.html", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": "-? --help", "source_url": "/docs/15/pgtesttiming.html", "description": "Show help about pg_test_timing command line arguments, and exit."}], "related": [], "release": {"ref": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "label": "15.19", "major": "15", "channel": "stable", "manifest": {"pdf": {"A4": {"url": "/files/documentation/pdf/15/postgresql-15-A4.pdf", "bytes": 14609140, "pages": 2987, "sha256": "66228564a4d16efb47d6a914085716ecfe22ca1566db56bc7c3d82f790646d72", "built_at": "2026-09-26"}, "US": {"url": "/files/documentation/pdf/15/postgresql-15-US.pdf", "bytes": 14495690, "pages": 3153, "sha256": "645a498c2390d47a6223ec74770631185807a19c484edb0fc5a295d9f460bc02", "built_at": "2026-09-26"}}, "tree": "15", "index": "index.html", "major": "15", "pages": 1168, "release": "15.19", "source_url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "svg_assets": 3, "source_mode": "en HTML verified against the pinned official archive", "source_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}, "revision": "6af958c6520151fc7697d56e0616b03fb00522c4568158674d452ae0644ba545", "evidence_kind": "English manual and source declarations", "source_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}, "sources": [{"url": "/docs/15/pgtesttiming.html", "file": "pgtesttiming.html", "label": "15.19 English manual \u00b7 pgtesttiming.html", "anchor": "", "sha256": "a5aca463b9f3017537591afc4f8d6987025ca0afc94776a2cf99fc5a526790fa"}, {"url": "/docs/15/reference-server.html", "file": "reference-server.html", "label": "Server applications inventory", "anchor": "", "sha256": "1240cfbb13ebfd22aac8d5ae40c62a9015b246f7774bcf0bce97355ce06350a0"}], "sections": [], "synopsis": ["pg_test_timing [ option ...]"], "signature": "pg_test_timing [ option ...]", "description": ["pg_test_timing \u2014 measure timing overhead"], "environment": [], "manual_html": "<div><div class=\"refentry\" id=\"PGTESTTIMING\">\n<div class=\"titlepage\"></div>\n<div class=\"refnamediv\">\n<h2><span class=\"refentrytitle\"><span class=\"application\">pg_test_timing</span></span></h2>\n<p>pg_test_timing \u2014 measure timing overhead</p>\n</div>\n<div class=\"refsynopsisdiv\">\n<h2>Synopsis</h2>\n<div class=\"cmdsynopsis\">\n<p id=\"id-1.9.5.11.4.1\"><code class=\"command\">pg_test_timing</code> [<em class=\"replaceable\"><code>option</code></em>...]</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.5\">\n<h2>Description</h2>\n<p><span class=\"application\">pg_test_timing</span> is a tool to measure the timing overhead on your system and confirm that the system time never moves backwards. Systems that are slow to collect timing data can give less accurate <code class=\"command\">EXPLAIN ANALYZE</code> results.</p>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.6\">\n<h2>Options</h2>\n<p><span class=\"application\">pg_test_timing</span> accepts the following command-line options:</p>\n<div class=\"variablelist\">\n<dl class=\"variablelist\">\n<dt><span class=\"term\"><code class=\"option\">-d <em class=\"replaceable\"><code>duration</code></em></code><br></span><span class=\"term\"><code class=\"option\">--duration=<em class=\"replaceable\"><code>duration</code></em></code></span></dt>\n<dd>\n<p>Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-V</code><br></span><span class=\"term\"><code class=\"option\">--version</code></span></dt>\n<dd>\n<p>Print the <span class=\"application\">pg_test_timing</span> version and exit.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-?</code><br></span><span class=\"term\"><code class=\"option\">--help</code></span></dt>\n<dd>\n<p>Show help about <span class=\"application\">pg_test_timing</span> command line arguments, and exit.</p>\n</dd>\n</dl>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.7\">\n<h2>Usage</h2>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.2\">\n<h3>Interpreting Results</h3>\n<p>Good results will show most (&gt;90%) individual timing calls take less than one microsecond. Average per loop overhead will be even lower, below 100 nanoseconds. This example from an Intel i7-860 system using a TSC clock source shows excellent performance:</p>\n<pre class=\"screen\">Testing timing overhead for 3 seconds.\nPer loop time including overhead: 35.96 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     96.40465   80435604\n     2      3.59518    2999652\n     4      0.00015        126\n     8      0.00002         13\n    16      0.00000          2\n</pre>\n<p>Note that different units are used for the per loop time than the histogram. The loop can have resolution within a few nanoseconds (ns), while the individual timing calls can only resolve down to one microsecond (us).</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.3\">\n<h3>Measuring Executor Timing Overhead</h3>\n<p>When the query executor is running a statement using <code class=\"command\">EXPLAIN ANALYZE</code>, individual operations are timed as well as showing a summary. The overhead of your system can be checked by counting rows with the <span class=\"application\">psql</span> program:</p>\n<pre class=\"screen\">CREATE TABLE t AS SELECT * FROM generate_series(1,100000);\n\\timing\nSELECT COUNT(*) FROM t;\nEXPLAIN ANALYZE SELECT COUNT(*) FROM t;\n</pre>\n<p>The i7-860 system measured runs the count query in 9.8 ms while the <code class=\"command\">EXPLAIN ANALYZE</code> version takes 16.6 ms, each processing just over 100,000 rows. That 6.8 ms difference means the timing overhead per row is 68 ns, about twice what pg_test_timing estimated it would be. Even that relatively small amount of overhead is making the fully timed count statement take almost 70% longer. On more substantial queries, the timing overhead would be less problematic.</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.4\">\n<h3>Changing Time Sources</h3>\n<p>On some newer Linux systems, it's possible to change the clock source used to collect timing data at any time. A second example shows the slowdown possible from switching to the slower acpi_pm time source, on the same system used for the fast results above:</p>\n<pre class=\"screen\"># cat /sys/devices/system/clocksource/clocksource0/available_clocksource\ntsc hpet acpi_pm\n# echo acpi_pm &gt; /sys/devices/system/clocksource/clocksource0/current_clocksource\n# pg_test_timing\nPer loop time including overhead: 722.92 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     27.84870    1155682\n     2     72.05956    2990371\n     4      0.07810       3241\n     8      0.01357        563\n    16      0.00007          3\n</pre>\n<p>In this configuration, the sample <code class=\"command\">EXPLAIN ANALYZE</code> above takes 115.9 ms. That's 1061 ns of timing overhead, again a small multiple of what's measured directly by this utility. That much timing overhead means the actual query itself is only taking a tiny fraction of the accounted for time, most of it is being consumed in overhead instead. In this configuration, any <code class=\"command\">EXPLAIN ANALYZE</code> totals involving many timed operations would be inflated significantly by timing overhead.</p>\n<p>FreeBSD also allows changing the time source on the fly, and it logs information about the timer selected during boot:</p>\n<pre class=\"screen\"># dmesg | grep \"Timecounter\"\nTimecounter \"ACPI-fast\" frequency 3579545 Hz quality 900\nTimecounter \"i8254\" frequency 1193182 Hz quality 0\nTimecounters tick every 10.000 msec\nTimecounter \"TSC\" frequency 2531787134 Hz quality 800\n# sysctl kern.timecounter.hardware=TSC\nkern.timecounter.hardware: ACPI-fast -&gt; TSC\n</pre>\n<p>Other systems may only allow setting the time source on boot. On older Linux systems the \"clock\" kernel setting is the only way to make this sort of change. And even on some more recent ones, the only option you'll see for a clock source is \"jiffies\". Jiffies are the older Linux software clock implementation, which can have good resolution when it's backed by fast enough timing hardware, as in this example:</p>\n<pre class=\"screen\">$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource\njiffies\n$ dmesg | grep time.c\ntime.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.\ntime.c: Detected 2400.153 MHz processor.\n$ pg_test_timing\nTesting timing overhead for 3 seconds.\nPer timing duration including loop overhead: 97.75 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     90.23734   27694571\n     2      9.75277    2993204\n     4      0.00981       3010\n     8      0.00007         22\n    16      0.00000          1\n    32      0.00000          1\n</pre>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.5\">\n<h3>Clock Hardware and Timing Accuracy</h3>\n<p>Collecting accurate timing information is normally done on computers using hardware clocks with various levels of accuracy. With some hardware the operating systems can pass the system clock time almost directly to programs. A system clock can also be derived from a chip that simply provides timing interrupts, periodic ticks at some known time interval. In either case, operating system kernels provide a clock source that hides these details. But the accuracy of that clock source and how quickly it can return results varies based on the underlying hardware.</p>\n<p>Inaccurate time keeping can result in system instability. Test any change to the clock source very carefully. Operating system defaults are sometimes made to favor reliability over best accuracy. And if you are using a virtual machine, look into the recommended time sources compatible with it. Virtual hardware faces additional difficulties when emulating timers, and there are often per operating system settings suggested by vendors.</p>\n<p>The Time Stamp Counter (TSC) clock source is the most accurate one available on current generation CPUs. It's the preferred way to track the system time when it's supported by the operating system and the TSC clock is reliable. There are several ways that TSC can fail to provide an accurate timing source, making it unreliable. Older systems can have a TSC clock that varies based on the CPU temperature, making it unusable for timing. Trying to use TSC on some older multicore CPUs can give a reported time that's inconsistent among multiple cores. This can result in the time going backwards, a problem this program checks for. And even the newest systems can fail to provide accurate TSC timing with very aggressive power saving configurations.</p>\n<p>Newer operating systems may check for the known TSC problems and switch to a slower, more stable clock source when they are seen. If your system supports TSC time but doesn't default to that, it may be disabled for a good reason. And some operating systems may not detect all the possible problems correctly, or will allow using TSC even in situations where it's known to be inaccurate.</p>\n<p>The High Precision Event Timer (HPET) is the preferred timer on systems where it's available and TSC is not accurate. The timer chip itself is programmable to allow up to 100 nanosecond resolution, but you may not see that much accuracy in your system clock.</p>\n<p>Advanced Configuration and Power Interface (ACPI) provides a Power Management (PM) Timer, which Linux refers to as the acpi_pm. The clock derived from acpi_pm will at best provide 300 nanosecond resolution.</p>\n<p>Timers used on older PC hardware include the 8254 Programmable Interval Timer (PIT), the real-time clock (RTC), the Advanced Programmable Interrupt Controller (APIC) timer, and the Cyclone timer. These timers aim for millisecond resolution.</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.8\">\n<h2>See Also</h2><span class=\"simplelist\"><a class=\"xref\" href=\"/docs/15/sql-explain.html\" title=\"EXPLAIN\"><span class=\"refentrytitle\">EXPLAIN</span></a></span>\n</div>\n</div></div>", "manual_path": "pgtesttiming.html", "comparison_data": {"options": [{"names": ["-d duration", "--duration= duration"], "signature": "-d duration --duration= duration", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "signature": "-V --version", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "signature": "-? --help", "description": "Show help about pg_test_timing command line arguments, and exit."}], "synopsis": ["pg_test_timing [ option ...]"], "environment": []}, "comparison_hash": "1e9850049374c38671166c0a5cf0759d6f33dd01f733985211c9962ac16213b4"}, "16": {"facts": [{"label": "Documented executable", "value": "pg_test_timing"}, {"label": "Executable version", "value": "16.15"}, {"label": "Reference inventory", "value": "Server applications"}, {"label": "Option definition groups", "value": "3"}], "tables": [{"key": "options", "rows": [{"summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": {"url": "/docs/16/pgtesttiming.html", "text": "-d duration --duration= duration"}}, {"summary": "Print the pg_test_timing version and exit.", "signature": {"url": "/docs/16/pgtesttiming.html", "text": "-V --version"}}, {"summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": {"url": "/docs/16/pgtesttiming.html", "text": "-? --help"}}], "title": "Documented options", "columns": [{"key": "signature", "label": "Option and arguments"}, {"key": "summary", "label": "Description"}]}], "options": [{"names": ["-d duration", "--duration= duration"], "summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": "-d duration --duration= duration", "source_url": "/docs/16/pgtesttiming.html", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "summary": "Print the pg_test_timing version and exit.", "signature": "-V --version", "source_url": "/docs/16/pgtesttiming.html", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": "-? --help", "source_url": "/docs/16/pgtesttiming.html", "description": "Show help about pg_test_timing command line arguments, and exit."}], "related": [], "release": {"ref": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "label": "16.15", "major": "16", "channel": "stable", "manifest": {"pdf": {"A4": {"url": "/files/documentation/pdf/16/postgresql-16-A4.pdf", "bytes": 15282337, "pages": 3055, "sha256": "4bb6c1f63deedac98736d8c4c7bc0fad0ac24e85b07e21ee10411872f06afd06", "built_at": "2026-09-26"}, "US": {"url": "/files/documentation/pdf/16/postgresql-16-US.pdf", "bytes": 15164148, "pages": 3220, "sha256": "5b6b6166c89991199e144bb0ae34c17a5f29826251dbf19db1abc0df3a3e771b", "built_at": "2026-09-26"}}, "tree": "16", "index": "index.html", "major": "16", "pages": 1169, "release": "16.15", "source_url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "svg_assets": 3, "source_mode": "en HTML verified against the pinned official archive", "source_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}, "revision": "3c21e58b35318021716440e67bb8bafd392b6a2b965a244d90e9e33c99e0bdef", "evidence_kind": "English manual and source declarations", "source_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}, "sources": [{"url": "/docs/16/pgtesttiming.html", "file": "pgtesttiming.html", "label": "16.15 English manual \u00b7 pgtesttiming.html", "anchor": "", "sha256": "2fb73387c5fb23f8b867c4f8b81d0f1247f8f0255d99591153b74e6adeeeff3f"}, {"url": "/docs/16/reference-server.html", "file": "reference-server.html", "label": "Server applications inventory", "anchor": "", "sha256": "8aaa4422eece8f26d84715f855d9d0f7f87b200f8b82898c73c865ee42c2c70f"}], "sections": [], "synopsis": ["pg_test_timing [ option ...]"], "signature": "pg_test_timing [ option ...]", "description": ["pg_test_timing \u2014 measure timing overhead"], "environment": [], "manual_html": "<div><div class=\"refentry\" id=\"PGTESTTIMING\">\n<div class=\"titlepage\"></div>\n<div class=\"refnamediv\">\n<h2><span class=\"refentrytitle\"><span class=\"application\">pg_test_timing</span></span></h2>\n<p>pg_test_timing \u2014 measure timing overhead</p>\n</div>\n<div class=\"refsynopsisdiv\">\n<h2>Synopsis</h2>\n<div class=\"cmdsynopsis\">\n<p id=\"id-1.9.5.11.4.1\"><code class=\"command\">pg_test_timing</code> [<em class=\"replaceable\"><code>option</code></em>...]</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.5\">\n<h2>Description</h2>\n<p><span class=\"application\">pg_test_timing</span> is a tool to measure the timing overhead on your system and confirm that the system time never moves backwards. Systems that are slow to collect timing data can give less accurate <code class=\"command\">EXPLAIN ANALYZE</code> results.</p>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.6\">\n<h2>Options</h2>\n<p><span class=\"application\">pg_test_timing</span> accepts the following command-line options:</p>\n<div class=\"variablelist\">\n<dl class=\"variablelist\">\n<dt><span class=\"term\"><code class=\"option\">-d <em class=\"replaceable\"><code>duration</code></em></code><br></span><span class=\"term\"><code class=\"option\">--duration=<em class=\"replaceable\"><code>duration</code></em></code></span></dt>\n<dd>\n<p>Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-V</code><br></span><span class=\"term\"><code class=\"option\">--version</code></span></dt>\n<dd>\n<p>Print the <span class=\"application\">pg_test_timing</span> version and exit.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-?</code><br></span><span class=\"term\"><code class=\"option\">--help</code></span></dt>\n<dd>\n<p>Show help about <span class=\"application\">pg_test_timing</span> command line arguments, and exit.</p>\n</dd>\n</dl>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.7\">\n<h2>Usage</h2>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.2\">\n<h3>Interpreting Results</h3>\n<p>Good results will show most (&gt;90%) individual timing calls take less than one microsecond. Average per loop overhead will be even lower, below 100 nanoseconds. This example from an Intel i7-860 system using a TSC clock source shows excellent performance:</p>\n<pre class=\"screen\">Testing timing overhead for 3 seconds.\nPer loop time including overhead: 35.96 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     96.40465   80435604\n     2      3.59518    2999652\n     4      0.00015        126\n     8      0.00002         13\n    16      0.00000          2\n</pre>\n<p>Note that different units are used for the per loop time than the histogram. The loop can have resolution within a few nanoseconds (ns), while the individual timing calls can only resolve down to one microsecond (us).</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.3\">\n<h3>Measuring Executor Timing Overhead</h3>\n<p>When the query executor is running a statement using <code class=\"command\">EXPLAIN ANALYZE</code>, individual operations are timed as well as showing a summary. The overhead of your system can be checked by counting rows with the <span class=\"application\">psql</span> program:</p>\n<pre class=\"screen\">CREATE TABLE t AS SELECT * FROM generate_series(1,100000);\n\\timing\nSELECT COUNT(*) FROM t;\nEXPLAIN ANALYZE SELECT COUNT(*) FROM t;\n</pre>\n<p>The i7-860 system measured runs the count query in 9.8 ms while the <code class=\"command\">EXPLAIN ANALYZE</code> version takes 16.6 ms, each processing just over 100,000 rows. That 6.8 ms difference means the timing overhead per row is 68 ns, about twice what pg_test_timing estimated it would be. Even that relatively small amount of overhead is making the fully timed count statement take almost 70% longer. On more substantial queries, the timing overhead would be less problematic.</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.4\">\n<h3>Changing Time Sources</h3>\n<p>On some newer Linux systems, it's possible to change the clock source used to collect timing data at any time. A second example shows the slowdown possible from switching to the slower acpi_pm time source, on the same system used for the fast results above:</p>\n<pre class=\"screen\"># cat /sys/devices/system/clocksource/clocksource0/available_clocksource\ntsc hpet acpi_pm\n# echo acpi_pm &gt; /sys/devices/system/clocksource/clocksource0/current_clocksource\n# pg_test_timing\nPer loop time including overhead: 722.92 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     27.84870    1155682\n     2     72.05956    2990371\n     4      0.07810       3241\n     8      0.01357        563\n    16      0.00007          3\n</pre>\n<p>In this configuration, the sample <code class=\"command\">EXPLAIN ANALYZE</code> above takes 115.9 ms. That's 1061 ns of timing overhead, again a small multiple of what's measured directly by this utility. That much timing overhead means the actual query itself is only taking a tiny fraction of the accounted for time, most of it is being consumed in overhead instead. In this configuration, any <code class=\"command\">EXPLAIN ANALYZE</code> totals involving many timed operations would be inflated significantly by timing overhead.</p>\n<p>FreeBSD also allows changing the time source on the fly, and it logs information about the timer selected during boot:</p>\n<pre class=\"screen\"># dmesg | grep \"Timecounter\"\nTimecounter \"ACPI-fast\" frequency 3579545 Hz quality 900\nTimecounter \"i8254\" frequency 1193182 Hz quality 0\nTimecounters tick every 10.000 msec\nTimecounter \"TSC\" frequency 2531787134 Hz quality 800\n# sysctl kern.timecounter.hardware=TSC\nkern.timecounter.hardware: ACPI-fast -&gt; TSC\n</pre>\n<p>Other systems may only allow setting the time source on boot. On older Linux systems the \"clock\" kernel setting is the only way to make this sort of change. And even on some more recent ones, the only option you'll see for a clock source is \"jiffies\". Jiffies are the older Linux software clock implementation, which can have good resolution when it's backed by fast enough timing hardware, as in this example:</p>\n<pre class=\"screen\">$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource\njiffies\n$ dmesg | grep time.c\ntime.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.\ntime.c: Detected 2400.153 MHz processor.\n$ pg_test_timing\nTesting timing overhead for 3 seconds.\nPer timing duration including loop overhead: 97.75 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     90.23734   27694571\n     2      9.75277    2993204\n     4      0.00981       3010\n     8      0.00007         22\n    16      0.00000          1\n    32      0.00000          1\n</pre>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.11.7.5\">\n<h3>Clock Hardware and Timing Accuracy</h3>\n<p>Collecting accurate timing information is normally done on computers using hardware clocks with various levels of accuracy. With some hardware the operating systems can pass the system clock time almost directly to programs. A system clock can also be derived from a chip that simply provides timing interrupts, periodic ticks at some known time interval. In either case, operating system kernels provide a clock source that hides these details. But the accuracy of that clock source and how quickly it can return results varies based on the underlying hardware.</p>\n<p>Inaccurate time keeping can result in system instability. Test any change to the clock source very carefully. Operating system defaults are sometimes made to favor reliability over best accuracy. And if you are using a virtual machine, look into the recommended time sources compatible with it. Virtual hardware faces additional difficulties when emulating timers, and there are often per operating system settings suggested by vendors.</p>\n<p>The Time Stamp Counter (TSC) clock source is the most accurate one available on current generation CPUs. It's the preferred way to track the system time when it's supported by the operating system and the TSC clock is reliable. There are several ways that TSC can fail to provide an accurate timing source, making it unreliable. Older systems can have a TSC clock that varies based on the CPU temperature, making it unusable for timing. Trying to use TSC on some older multicore CPUs can give a reported time that's inconsistent among multiple cores. This can result in the time going backwards, a problem this program checks for. And even the newest systems can fail to provide accurate TSC timing with very aggressive power saving configurations.</p>\n<p>Newer operating systems may check for the known TSC problems and switch to a slower, more stable clock source when they are seen. If your system supports TSC time but doesn't default to that, it may be disabled for a good reason. And some operating systems may not detect all the possible problems correctly, or will allow using TSC even in situations where it's known to be inaccurate.</p>\n<p>The High Precision Event Timer (HPET) is the preferred timer on systems where it's available and TSC is not accurate. The timer chip itself is programmable to allow up to 100 nanosecond resolution, but you may not see that much accuracy in your system clock.</p>\n<p>Advanced Configuration and Power Interface (ACPI) provides a Power Management (PM) Timer, which Linux refers to as the acpi_pm. The clock derived from acpi_pm will at best provide 300 nanosecond resolution.</p>\n<p>Timers used on older PC hardware include the 8254 Programmable Interval Timer (PIT), the real-time clock (RTC), the Advanced Programmable Interrupt Controller (APIC) timer, and the Cyclone timer. These timers aim for millisecond resolution.</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.11.8\">\n<h2>See Also</h2><span class=\"simplelist\"><a class=\"xref\" href=\"/docs/16/sql-explain.html\" title=\"EXPLAIN\"><span class=\"refentrytitle\">EXPLAIN</span></a></span>\n</div>\n</div></div>", "manual_path": "pgtesttiming.html", "comparison_data": {"options": [{"names": ["-d duration", "--duration= duration"], "signature": "-d duration --duration= duration", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "signature": "-V --version", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "signature": "-? --help", "description": "Show help about pg_test_timing command line arguments, and exit."}], "synopsis": ["pg_test_timing [ option ...]"], "environment": []}, "comparison_hash": "1e9850049374c38671166c0a5cf0759d6f33dd01f733985211c9962ac16213b4"}, "17": {"facts": [{"label": "Documented executable", "value": "pg_test_timing"}, {"label": "Executable version", "value": "17.11"}, {"label": "Reference inventory", "value": "Server applications"}, {"label": "Option definition groups", "value": "3"}], "tables": [{"key": "options", "rows": [{"summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": {"url": "/docs/17/pgtesttiming.html", "text": "-d duration --duration= duration"}}, {"summary": "Print the pg_test_timing version and exit.", "signature": {"url": "/docs/17/pgtesttiming.html", "text": "-V --version"}}, {"summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": {"url": "/docs/17/pgtesttiming.html", "text": "-? --help"}}], "title": "Documented options", "columns": [{"key": "signature", "label": "Option and arguments"}, {"key": "summary", "label": "Description"}]}], "options": [{"names": ["-d duration", "--duration= duration"], "summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": "-d duration --duration= duration", "source_url": "/docs/17/pgtesttiming.html", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "summary": "Print the pg_test_timing version and exit.", "signature": "-V --version", "source_url": "/docs/17/pgtesttiming.html", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": "-? --help", "source_url": "/docs/17/pgtesttiming.html", "description": "Show help about pg_test_timing command line arguments, and exit."}], "related": [], "release": {"ref": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "label": "17.11", "major": "17", "channel": "stable", "manifest": {"pdf": {"A4": {"url": "/files/documentation/pdf/17/postgresql-17-A4.pdf", "bytes": 15521293, "pages": 3099, "sha256": "1991354df0dc89e70ec39328c28988ef8b19c6a93671dab3893650b63e9f4e36", "built_at": "2026-09-26"}, "US": {"url": "/files/documentation/pdf/17/postgresql-17-US.pdf", "bytes": 15398150, "pages": 3270, "sha256": "07696c8f38abf31babf22d2db337093936e7c472d2af36d050b000c49bbcf52c", "built_at": "2026-09-26"}}, "tree": "17", "index": "index.html", "major": "17", "pages": 1143, "release": "17.11", "source_url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "svg_assets": 3, "source_mode": "en SGML built with pinned official archive", "source_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}, "revision": "58419c9b0dd42cb34c8d53695bb025a7e582edf55ccd4c5bcb1c2c7c71a37487", "evidence_kind": "English manual and source declarations", "source_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}, "sources": [{"url": "/docs/17/pgtesttiming.html", "file": "pgtesttiming.html", "label": "17.11 English manual \u00b7 pgtesttiming.html", "anchor": "", "sha256": "964f3ce1ef6b944f1a40bb3134c4d679e86d96538b729985f58f9b743ba9d6e8"}, {"url": "/docs/17/reference-server.html", "file": "reference-server.html", "label": "Server applications inventory", "anchor": "", "sha256": "01f07993ff020684f4c290d17cdafa26fb17ea5c1d476bc3a5efc68bf8ddd9b9"}], "sections": [], "synopsis": ["pg_test_timing [ option ...]"], "signature": "pg_test_timing [ option ...]", "description": ["pg_test_timing \u2014 measure timing overhead"], "environment": [], "manual_html": "<div><div class=\"refentry\" id=\"PGTESTTIMING\">\n<div class=\"titlepage\"></div>\n<div class=\"refnamediv\">\n<h2><span class=\"refentrytitle\"><span class=\"application\">pg_test_timing</span></span></h2>\n<p>pg_test_timing \u2014 measure timing overhead</p>\n</div>\n<div class=\"refsynopsisdiv\">\n<h2>Synopsis</h2>\n<div class=\"cmdsynopsis\">\n<p id=\"id-1.9.5.12.4.1\"><code class=\"command\">pg_test_timing</code> [<em class=\"replaceable\"><code>option</code></em>...]</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.5\">\n<h2>Description</h2>\n<p><span class=\"application\">pg_test_timing</span> is a tool to measure the timing overhead on your system and confirm that the system time never moves backwards. Systems that are slow to collect timing data can give less accurate <code class=\"command\">EXPLAIN ANALYZE</code> results.</p>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.6\">\n<h2>Options</h2>\n<p><span class=\"application\">pg_test_timing</span> accepts the following command-line options:</p>\n<div class=\"variablelist\">\n<dl class=\"variablelist\">\n<dt><span class=\"term\"><code class=\"option\">-d <em class=\"replaceable\"><code>duration</code></em></code><br></span><span class=\"term\"><code class=\"option\">--duration=<em class=\"replaceable\"><code>duration</code></em></code></span></dt>\n<dd>\n<p>Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-V</code><br></span><span class=\"term\"><code class=\"option\">--version</code></span></dt>\n<dd>\n<p>Print the <span class=\"application\">pg_test_timing</span> version and exit.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-?</code><br></span><span class=\"term\"><code class=\"option\">--help</code></span></dt>\n<dd>\n<p>Show help about <span class=\"application\">pg_test_timing</span> command line arguments, and exit.</p>\n</dd>\n</dl>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.7\">\n<h2>Usage</h2>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.2\">\n<h3>Interpreting Results</h3>\n<p>Good results will show most (&gt;90%) individual timing calls take less than one microsecond. Average per loop overhead will be even lower, below 100 nanoseconds. This example from an Intel i7-860 system using a TSC clock source shows excellent performance:</p>\n<pre class=\"screen\">Testing timing overhead for 3 seconds.\nPer loop time including overhead: 35.96 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     96.40465   80435604\n     2      3.59518    2999652\n     4      0.00015        126\n     8      0.00002         13\n    16      0.00000          2\n</pre>\n<p>Note that different units are used for the per loop time than the histogram. The loop can have resolution within a few nanoseconds (ns), while the individual timing calls can only resolve down to one microsecond (us).</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.3\">\n<h3>Measuring Executor Timing Overhead</h3>\n<p>When the query executor is running a statement using <code class=\"command\">EXPLAIN ANALYZE</code>, individual operations are timed as well as showing a summary. The overhead of your system can be checked by counting rows with the <span class=\"application\">psql</span> program:</p>\n<pre class=\"screen\">CREATE TABLE t AS SELECT * FROM generate_series(1,100000);\n\\timing\nSELECT COUNT(*) FROM t;\nEXPLAIN ANALYZE SELECT COUNT(*) FROM t;\n</pre>\n<p>The i7-860 system measured runs the count query in 9.8 ms while the <code class=\"command\">EXPLAIN ANALYZE</code> version takes 16.6 ms, each processing just over 100,000 rows. That 6.8 ms difference means the timing overhead per row is 68 ns, about twice what pg_test_timing estimated it would be. Even that relatively small amount of overhead is making the fully timed count statement take almost 70% longer. On more substantial queries, the timing overhead would be less problematic.</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.4\">\n<h3>Changing Time Sources</h3>\n<p>On some newer Linux systems, it's possible to change the clock source used to collect timing data at any time. A second example shows the slowdown possible from switching to the slower acpi_pm time source, on the same system used for the fast results above:</p>\n<pre class=\"screen\"># cat /sys/devices/system/clocksource/clocksource0/available_clocksource\ntsc hpet acpi_pm\n# echo acpi_pm &gt; /sys/devices/system/clocksource/clocksource0/current_clocksource\n# pg_test_timing\nPer loop time including overhead: 722.92 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     27.84870    1155682\n     2     72.05956    2990371\n     4      0.07810       3241\n     8      0.01357        563\n    16      0.00007          3\n</pre>\n<p>In this configuration, the sample <code class=\"command\">EXPLAIN ANALYZE</code> above takes 115.9 ms. That's 1061 ns of timing overhead, again a small multiple of what's measured directly by this utility. That much timing overhead means the actual query itself is only taking a tiny fraction of the accounted for time, most of it is being consumed in overhead instead. In this configuration, any <code class=\"command\">EXPLAIN ANALYZE</code> totals involving many timed operations would be inflated significantly by timing overhead.</p>\n<p>FreeBSD also allows changing the time source on the fly, and it logs information about the timer selected during boot:</p>\n<pre class=\"screen\"># dmesg | grep \"Timecounter\"\nTimecounter \"ACPI-fast\" frequency 3579545 Hz quality 900\nTimecounter \"i8254\" frequency 1193182 Hz quality 0\nTimecounters tick every 10.000 msec\nTimecounter \"TSC\" frequency 2531787134 Hz quality 800\n# sysctl kern.timecounter.hardware=TSC\nkern.timecounter.hardware: ACPI-fast -&gt; TSC\n</pre>\n<p>Other systems may only allow setting the time source on boot. On older Linux systems the \"clock\" kernel setting is the only way to make this sort of change. And even on some more recent ones, the only option you'll see for a clock source is \"jiffies\". Jiffies are the older Linux software clock implementation, which can have good resolution when it's backed by fast enough timing hardware, as in this example:</p>\n<pre class=\"screen\">$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource\njiffies\n$ dmesg | grep time.c\ntime.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.\ntime.c: Detected 2400.153 MHz processor.\n$ pg_test_timing\nTesting timing overhead for 3 seconds.\nPer timing duration including loop overhead: 97.75 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     90.23734   27694571\n     2      9.75277    2993204\n     4      0.00981       3010\n     8      0.00007         22\n    16      0.00000          1\n    32      0.00000          1\n</pre>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.5\">\n<h3>Clock Hardware and Timing Accuracy</h3>\n<p>Collecting accurate timing information is normally done on computers using hardware clocks with various levels of accuracy. With some hardware the operating systems can pass the system clock time almost directly to programs. A system clock can also be derived from a chip that simply provides timing interrupts, periodic ticks at some known time interval. In either case, operating system kernels provide a clock source that hides these details. But the accuracy of that clock source and how quickly it can return results varies based on the underlying hardware.</p>\n<p>Inaccurate time keeping can result in system instability. Test any change to the clock source very carefully. Operating system defaults are sometimes made to favor reliability over best accuracy. And if you are using a virtual machine, look into the recommended time sources compatible with it. Virtual hardware faces additional difficulties when emulating timers, and there are often per operating system settings suggested by vendors.</p>\n<p>The Time Stamp Counter (TSC) clock source is the most accurate one available on current generation CPUs. It's the preferred way to track the system time when it's supported by the operating system and the TSC clock is reliable. There are several ways that TSC can fail to provide an accurate timing source, making it unreliable. Older systems can have a TSC clock that varies based on the CPU temperature, making it unusable for timing. Trying to use TSC on some older multicore CPUs can give a reported time that's inconsistent among multiple cores. This can result in the time going backwards, a problem this program checks for. And even the newest systems can fail to provide accurate TSC timing with very aggressive power saving configurations.</p>\n<p>Newer operating systems may check for the known TSC problems and switch to a slower, more stable clock source when they are seen. If your system supports TSC time but doesn't default to that, it may be disabled for a good reason. And some operating systems may not detect all the possible problems correctly, or will allow using TSC even in situations where it's known to be inaccurate.</p>\n<p>The High Precision Event Timer (HPET) is the preferred timer on systems where it's available and TSC is not accurate. The timer chip itself is programmable to allow up to 100 nanosecond resolution, but you may not see that much accuracy in your system clock.</p>\n<p>Advanced Configuration and Power Interface (ACPI) provides a Power Management (PM) Timer, which Linux refers to as the acpi_pm. The clock derived from acpi_pm will at best provide 300 nanosecond resolution.</p>\n<p>Timers used on older PC hardware include the 8254 Programmable Interval Timer (PIT), the real-time clock (RTC), the Advanced Programmable Interrupt Controller (APIC) timer, and the Cyclone timer. These timers aim for millisecond resolution.</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.8\">\n<h2>See Also</h2><span class=\"simplelist\"><a class=\"xref\" href=\"/docs/17/sql-explain.html\" title=\"EXPLAIN\"><span class=\"refentrytitle\">EXPLAIN</span></a></span>\n</div>\n</div></div>", "manual_path": "pgtesttiming.html", "comparison_data": {"options": [{"names": ["-d duration", "--duration= duration"], "signature": "-d duration --duration= duration", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "signature": "-V --version", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "signature": "-? --help", "description": "Show help about pg_test_timing command line arguments, and exit."}], "synopsis": ["pg_test_timing [ option ...]"], "environment": []}, "comparison_hash": "1e9850049374c38671166c0a5cf0759d6f33dd01f733985211c9962ac16213b4"}, "18": {"facts": [{"label": "Documented executable", "value": "pg_test_timing"}, {"label": "Executable version", "value": "18.6"}, {"label": "Reference inventory", "value": "Server applications"}, {"label": "Option definition groups", "value": "3"}], "tables": [{"key": "options", "rows": [{"summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": {"url": "/docs/18/pgtesttiming.html", "text": "-d duration --duration= duration"}}, {"summary": "Print the pg_test_timing version and exit.", "signature": {"url": "/docs/18/pgtesttiming.html", "text": "-V --version"}}, {"summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": {"url": "/docs/18/pgtesttiming.html", "text": "-? --help"}}], "title": "Documented options", "columns": [{"key": "signature", "label": "Option and arguments"}, {"key": "summary", "label": "Description"}]}], "options": [{"names": ["-d duration", "--duration= duration"], "summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": "-d duration --duration= duration", "source_url": "/docs/18/pgtesttiming.html", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "summary": "Print the pg_test_timing version and exit.", "signature": "-V --version", "source_url": "/docs/18/pgtesttiming.html", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": "-? --help", "source_url": "/docs/18/pgtesttiming.html", "description": "Show help about pg_test_timing command line arguments, and exit."}], "related": [], "release": {"ref": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "label": "18.6", "major": "18", "channel": "stable", "manifest": {"pdf": {"A4": {"url": "/files/documentation/pdf/18/postgresql-18-A4.pdf", "bytes": 15865106, "pages": 3154, "sha256": "19512c405da53f9f7fcf0abba359223aa65f021be025bf3411381918f92e3190", "built_at": "2026-09-26"}, "US": {"url": "/files/documentation/pdf/18/postgresql-18-US.pdf", "bytes": 15748059, "pages": 3328, "sha256": "facbe6c229e598b872d3d98bef53308f46e06746006fa4590de9a7de9dd46319", "built_at": "2026-09-26"}}, "tree": "18", "index": "index.html", "major": "18", "pages": 1148, "release": "18.6", "source_url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "svg_assets": 3, "source_mode": "en SGML built with pinned official archive", "source_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, "revision": "ee8d1a3612338fd9adf250730cb640fcc5233b5491337cc00a316a44e3a0b9f8", "evidence_kind": "English manual and source declarations", "source_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, "sources": [{"url": "/docs/18/pgtesttiming.html", "file": "pgtesttiming.html", "label": "18.6 English manual \u00b7 pgtesttiming.html", "anchor": "", "sha256": "8766dacb1c3fc7b8afd518c8cf1165ac81c82eef9375dc6d3e1a7ae2e99962f5"}, {"url": "/docs/18/reference-server.html", "file": "reference-server.html", "label": "Server applications inventory", "anchor": "", "sha256": "e9f8bbcc8e3641fadd1d20991e8aad6b532155b786ba5a1b7b364ec4f1a5bef3"}], "sections": [], "synopsis": ["pg_test_timing [ option ...]"], "signature": "pg_test_timing [ option ...]", "description": ["pg_test_timing \u2014 measure timing overhead"], "environment": [], "manual_html": "<div><div class=\"refentry\" id=\"PGTESTTIMING\">\n<div class=\"titlepage\"></div>\n<div class=\"refnamediv\">\n<h2><span class=\"refentrytitle\"><span class=\"application\">pg_test_timing</span></span></h2>\n<p>pg_test_timing \u2014 measure timing overhead</p>\n</div>\n<div class=\"refsynopsisdiv\">\n<h2>Synopsis</h2>\n<div class=\"cmdsynopsis\">\n<p id=\"id-1.9.5.12.4.1\"><code class=\"command\">pg_test_timing</code> [<em class=\"replaceable\"><code>option</code></em>...]</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.5\">\n<h2>Description</h2>\n<p><span class=\"application\">pg_test_timing</span> is a tool to measure the timing overhead on your system and confirm that the system time never moves backwards. Systems that are slow to collect timing data can give less accurate <code class=\"command\">EXPLAIN ANALYZE</code> results.</p>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.6\">\n<h2>Options</h2>\n<p><span class=\"application\">pg_test_timing</span> accepts the following command-line options:</p>\n<div class=\"variablelist\">\n<dl class=\"variablelist\">\n<dt><span class=\"term\"><code class=\"option\">-d <em class=\"replaceable\"><code>duration</code></em></code><br></span><span class=\"term\"><code class=\"option\">--duration=<em class=\"replaceable\"><code>duration</code></em></code></span></dt>\n<dd>\n<p>Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-V</code><br></span><span class=\"term\"><code class=\"option\">--version</code></span></dt>\n<dd>\n<p>Print the <span class=\"application\">pg_test_timing</span> version and exit.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-?</code><br></span><span class=\"term\"><code class=\"option\">--help</code></span></dt>\n<dd>\n<p>Show help about <span class=\"application\">pg_test_timing</span> command line arguments, and exit.</p>\n</dd>\n</dl>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.7\">\n<h2>Usage</h2>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.2\">\n<h3>Interpreting Results</h3>\n<p>Good results will show most (&gt;90%) individual timing calls take less than one microsecond. Average per loop overhead will be even lower, below 100 nanoseconds. This example from an Intel i7-860 system using a TSC clock source shows excellent performance:</p>\n<pre class=\"screen\">Testing timing overhead for 3 seconds.\nPer loop time including overhead: 35.96 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     96.40465   80435604\n     2      3.59518    2999652\n     4      0.00015        126\n     8      0.00002         13\n    16      0.00000          2\n</pre>\n<p>Note that different units are used for the per loop time than the histogram. The loop can have resolution within a few nanoseconds (ns), while the individual timing calls can only resolve down to one microsecond (us).</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.3\">\n<h3>Measuring Executor Timing Overhead</h3>\n<p>When the query executor is running a statement using <code class=\"command\">EXPLAIN ANALYZE</code>, individual operations are timed as well as showing a summary. The overhead of your system can be checked by counting rows with the <span class=\"application\">psql</span> program:</p>\n<pre class=\"screen\">CREATE TABLE t AS SELECT * FROM generate_series(1,100000);\n\\timing\nSELECT COUNT(*) FROM t;\nEXPLAIN ANALYZE SELECT COUNT(*) FROM t;\n</pre>\n<p>The i7-860 system measured runs the count query in 9.8 ms while the <code class=\"command\">EXPLAIN ANALYZE</code> version takes 16.6 ms, each processing just over 100,000 rows. That 6.8 ms difference means the timing overhead per row is 68 ns, about twice what pg_test_timing estimated it would be. Even that relatively small amount of overhead is making the fully timed count statement take almost 70% longer. On more substantial queries, the timing overhead would be less problematic.</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.4\">\n<h3>Changing Time Sources</h3>\n<p>On some newer Linux systems, it's possible to change the clock source used to collect timing data at any time. A second example shows the slowdown possible from switching to the slower acpi_pm time source, on the same system used for the fast results above:</p>\n<pre class=\"screen\"># cat /sys/devices/system/clocksource/clocksource0/available_clocksource\ntsc hpet acpi_pm\n# echo acpi_pm &gt; /sys/devices/system/clocksource/clocksource0/current_clocksource\n# pg_test_timing\nPer loop time including overhead: 722.92 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     27.84870    1155682\n     2     72.05956    2990371\n     4      0.07810       3241\n     8      0.01357        563\n    16      0.00007          3\n</pre>\n<p>In this configuration, the sample <code class=\"command\">EXPLAIN ANALYZE</code> above takes 115.9 ms. That's 1061 ns of timing overhead, again a small multiple of what's measured directly by this utility. That much timing overhead means the actual query itself is only taking a tiny fraction of the accounted for time, most of it is being consumed in overhead instead. In this configuration, any <code class=\"command\">EXPLAIN ANALYZE</code> totals involving many timed operations would be inflated significantly by timing overhead.</p>\n<p>FreeBSD also allows changing the time source on the fly, and it logs information about the timer selected during boot:</p>\n<pre class=\"screen\"># dmesg | grep \"Timecounter\"\nTimecounter \"ACPI-fast\" frequency 3579545 Hz quality 900\nTimecounter \"i8254\" frequency 1193182 Hz quality 0\nTimecounters tick every 10.000 msec\nTimecounter \"TSC\" frequency 2531787134 Hz quality 800\n# sysctl kern.timecounter.hardware=TSC\nkern.timecounter.hardware: ACPI-fast -&gt; TSC\n</pre>\n<p>Other systems may only allow setting the time source on boot. On older Linux systems the \"clock\" kernel setting is the only way to make this sort of change. And even on some more recent ones, the only option you'll see for a clock source is \"jiffies\". Jiffies are the older Linux software clock implementation, which can have good resolution when it's backed by fast enough timing hardware, as in this example:</p>\n<pre class=\"screen\">$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource\njiffies\n$ dmesg | grep time.c\ntime.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.\ntime.c: Detected 2400.153 MHz processor.\n$ pg_test_timing\nTesting timing overhead for 3 seconds.\nPer timing duration including loop overhead: 97.75 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     90.23734   27694571\n     2      9.75277    2993204\n     4      0.00981       3010\n     8      0.00007         22\n    16      0.00000          1\n    32      0.00000          1\n</pre>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.5\">\n<h3>Clock Hardware and Timing Accuracy</h3>\n<p>Collecting accurate timing information is normally done on computers using hardware clocks with various levels of accuracy. With some hardware the operating systems can pass the system clock time almost directly to programs. A system clock can also be derived from a chip that simply provides timing interrupts, periodic ticks at some known time interval. In either case, operating system kernels provide a clock source that hides these details. But the accuracy of that clock source and how quickly it can return results varies based on the underlying hardware.</p>\n<p>Inaccurate time keeping can result in system instability. Test any change to the clock source very carefully. Operating system defaults are sometimes made to favor reliability over best accuracy. And if you are using a virtual machine, look into the recommended time sources compatible with it. Virtual hardware faces additional difficulties when emulating timers, and there are often per operating system settings suggested by vendors.</p>\n<p>The Time Stamp Counter (TSC) clock source is the most accurate one available on current generation CPUs. It's the preferred way to track the system time when it's supported by the operating system and the TSC clock is reliable. There are several ways that TSC can fail to provide an accurate timing source, making it unreliable. Older systems can have a TSC clock that varies based on the CPU temperature, making it unusable for timing. Trying to use TSC on some older multicore CPUs can give a reported time that's inconsistent among multiple cores. This can result in the time going backwards, a problem this program checks for. And even the newest systems can fail to provide accurate TSC timing with very aggressive power saving configurations.</p>\n<p>Newer operating systems may check for the known TSC problems and switch to a slower, more stable clock source when they are seen. If your system supports TSC time but doesn't default to that, it may be disabled for a good reason. And some operating systems may not detect all the possible problems correctly, or will allow using TSC even in situations where it's known to be inaccurate.</p>\n<p>The High Precision Event Timer (HPET) is the preferred timer on systems where it's available and TSC is not accurate. The timer chip itself is programmable to allow up to 100 nanosecond resolution, but you may not see that much accuracy in your system clock.</p>\n<p>Advanced Configuration and Power Interface (ACPI) provides a Power Management (PM) Timer, which Linux refers to as the acpi_pm. The clock derived from acpi_pm will at best provide 300 nanosecond resolution.</p>\n<p>Timers used on older PC hardware include the 8254 Programmable Interval Timer (PIT), the real-time clock (RTC), the Advanced Programmable Interrupt Controller (APIC) timer, and the Cyclone timer. These timers aim for millisecond resolution.</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.8\">\n<h2>See Also</h2><span class=\"simplelist\"><a class=\"xref\" href=\"/docs/18/sql-explain.html\" title=\"EXPLAIN\"><span class=\"refentrytitle\">EXPLAIN</span></a></span>\n</div>\n</div></div>", "manual_path": "pgtesttiming.html", "comparison_data": {"options": [{"names": ["-d duration", "--duration= duration"], "signature": "-d duration --duration= duration", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "signature": "-V --version", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "signature": "-? --help", "description": "Show help about pg_test_timing command line arguments, and exit."}], "synopsis": ["pg_test_timing [ option ...]"], "environment": []}, "comparison_hash": "1e9850049374c38671166c0a5cf0759d6f33dd01f733985211c9962ac16213b4"}, "19": {"facts": [{"label": "Documented executable", "value": "pg_test_timing"}, {"label": "Executable version", "value": "19beta4"}, {"label": "Reference inventory", "value": "Server applications"}, {"label": "Option definition groups", "value": "4"}], "tables": [{"key": "options", "rows": [{"summary": "Specifies the cutoff percentage for the list of exact observed timing durations (that is, the changes in the system clock value from one reading to the next). The list will end once the running percentage total reaches or exceeds this value, except that the largest observed duration will always be printed. The default cutoff is 99.99.", "signature": {"url": "/docs/19/pgtesttiming.html", "text": "-c cutoff --cutoff= cutoff"}}, {"summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": {"url": "/docs/19/pgtesttiming.html", "text": "-d duration --duration= duration"}}, {"summary": "Print the pg_test_timing version and exit.", "signature": {"url": "/docs/19/pgtesttiming.html", "text": "-V --version"}}, {"summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": {"url": "/docs/19/pgtesttiming.html", "text": "-? --help"}}], "title": "Documented options", "columns": [{"key": "signature", "label": "Option and arguments"}, {"key": "summary", "label": "Description"}]}], "options": [{"names": ["-c cutoff", "--cutoff= cutoff"], "summary": "Specifies the cutoff percentage for the list of exact observed timing durations (that is, the changes in the system clock value from one reading to the next). The list will end once the running percentage total reaches or exceeds this value, except that the largest observed duration will always be printed. The default cutoff is 99.99.", "signature": "-c cutoff --cutoff= cutoff", "source_url": "/docs/19/pgtesttiming.html", "description": "Specifies the cutoff percentage for the list of exact observed timing durations (that is, the changes in the system clock value from one reading to the next). The list will end once the running percentage total reaches or exceeds this value, except that the largest observed duration will always be printed. The default cutoff is 99.99."}, {"names": ["-d duration", "--duration= duration"], "summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": "-d duration --duration= duration", "source_url": "/docs/19/pgtesttiming.html", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "summary": "Print the pg_test_timing version and exit.", "signature": "-V --version", "source_url": "/docs/19/pgtesttiming.html", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": "-? --help", "source_url": "/docs/19/pgtesttiming.html", "description": "Show help about pg_test_timing command line arguments, and exit."}], "related": [], "release": {"ref": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "label": "19beta4", "major": "19", "channel": "preview", "manifest": {"pdf": {"A4": {"url": "/files/documentation/pdf/19/postgresql-19-A4.pdf", "bytes": 16064841, "pages": 3052, "sha256": "4dd099e4125c591128fc5f3ebd02178dc24781f9e5ae629f96d67c4c8547427b", "built_at": "2026-09-26"}, "US": {"url": "/files/documentation/pdf/19/postgresql-19-US.pdf", "bytes": 15974616, "pages": 3225, "sha256": "61971fa857f0956d47341a0388fa6af9ae10acf691d4b2fc009007d384b0342b", "built_at": "2026-09-26"}}, "tree": "19", "index": "index.html", "major": "19", "pages": 1155, "release": "19beta4", "source_url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "svg_assets": 5, "source_mode": "en SGML built with pinned official archive", "source_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}, "revision": "1bbbbf4133d426f0e4304010688d2984c30fb67df0cc3a61b3e37eb3f6f37833", "evidence_kind": "English manual and source declarations", "source_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}, "sources": [{"url": "/docs/19/pgtesttiming.html", "file": "pgtesttiming.html", "label": "19beta4 English manual \u00b7 pgtesttiming.html", "anchor": "", "sha256": "2dd2a25756595fb9663d5ff42fc5294b3fa6d8f1d4a407dba16e1f973f9333f1"}, {"url": "/docs/19/reference-server.html", "file": "reference-server.html", "label": "Server applications inventory", "anchor": "", "sha256": "425b070323b448b5516d2cb4e9e4ac77efb5d19dd4e8005d0ae1c61db9ec78e6"}], "sections": [], "synopsis": ["pg_test_timing [ option ...]"], "signature": "pg_test_timing [ option ...]", "description": ["pg_test_timing \u2014 measure timing overhead"], "environment": [], "manual_html": "<div><div class=\"refentry\" id=\"PGTESTTIMING\">\n<div class=\"titlepage\"></div>\n<div class=\"refnamediv\">\n<h2><span class=\"refentrytitle\"><span class=\"application\">pg_test_timing</span></span></h2>\n<p>pg_test_timing \u2014 measure timing overhead</p>\n</div>\n<div class=\"refsynopsisdiv\">\n<h2>Synopsis</h2>\n<div class=\"cmdsynopsis\">\n<p id=\"id-1.9.5.12.4.1\"><code class=\"command\">pg_test_timing</code> [<em class=\"replaceable\"><code>option</code></em>...]</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.5\">\n<h2>Description</h2>\n<p><span class=\"application\">pg_test_timing</span> is a tool to measure the timing overhead on your system and confirm that the system time never moves backwards. It reads supported clock sources over and over again as fast as it can for a specified length of time, and then prints statistics about the observed differences in successive clock readings, as well as which clock source will be used.</p>\n<p>Smaller (but not zero) differences are better, since they imply both more-precise clock hardware and less overhead to collect a clock reading. Systems that are slow to collect timing data can give less accurate <code class=\"command\">EXPLAIN ANALYZE</code> results.</p>\n<p>This tool is also helpful to determine if the <code class=\"varname\">track_io_timing</code> configuration parameter is likely to produce useful results, and whether the TSC clock source (see <a class=\"xref\" href=\"/docs/19/runtime-config-resource.html#GUC-TIMING-CLOCK-SOURCE\">timing_clock_source</a>) is available and if it will be used by default.</p>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.6\">\n<h2>Options</h2>\n<p><span class=\"application\">pg_test_timing</span> accepts the following command-line options:</p>\n<div class=\"variablelist\">\n<dl class=\"variablelist\">\n<dt><span class=\"term\"><code class=\"option\">-c <em class=\"replaceable\"><code>cutoff</code></em></code><br></span><span class=\"term\"><code class=\"option\">--cutoff=<em class=\"replaceable\"><code>cutoff</code></em></code></span></dt>\n<dd>\n<p>Specifies the cutoff percentage for the list of exact observed timing durations (that is, the changes in the system clock value from one reading to the next). The list will end once the running percentage total reaches or exceeds this value, except that the largest observed duration will always be printed. The default cutoff is 99.99.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-d <em class=\"replaceable\"><code>duration</code></em></code><br></span><span class=\"term\"><code class=\"option\">--duration=<em class=\"replaceable\"><code>duration</code></em></code></span></dt>\n<dd>\n<p>Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-V</code><br></span><span class=\"term\"><code class=\"option\">--version</code></span></dt>\n<dd>\n<p>Print the <span class=\"application\">pg_test_timing</span> version and exit.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-?</code><br></span><span class=\"term\"><code class=\"option\">--help</code></span></dt>\n<dd>\n<p>Show help about <span class=\"application\">pg_test_timing</span> command line arguments, and exit.</p>\n</dd>\n</dl>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.7\">\n<h2>Usage</h2>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.2\">\n<h3>Interpreting Results</h3>\n<p>The first block of output has four columns, with rows showing a shifted-by-one log2(ns) histogram of timing durations (that is, the differences between successive clock readings). This is not the classic log2(n+1) histogram as it counts zeros separately and then switches to log2(ns) starting from value 1.</p>\n<p>The columns are:</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist compact\">\n<li class=\"listitem\">nanosecond value that is &gt;= the durations in this bucket</li>\n<li class=\"listitem\">percentage of durations in this bucket</li>\n<li class=\"listitem\">running-sum percentage of durations in this and previous buckets</li>\n<li class=\"listitem\">count of durations in this bucket</li>\n</ul>\n</div>\n<p>The second block of output goes into more detail, showing the exact timing differences observed. For brevity this list is cut off when the running-sum percentage exceeds the user-selectable cutoff value. However, the largest observed difference is always shown.</p>\n<p>On platforms that support the TSC clock source, additional output sections are shown for the <code class=\"command\">RDTSCP</code> instruction (used for general timing needs, such as <code class=\"varname\">track_io_timing</code>) and the <code class=\"command\">RDTSC</code> instruction (used for <code class=\"command\">EXPLAIN ANALYZE</code>). At the end of the output, the TSC frequency, which may either be sourced from CPU information directly, or the alternate calibration mechanism are shown, as well as whether the TSC clock source will be used by default.</p>\n<p>The example results below show system clock timing where 99.99% of loops took between 16 and 63 nanoseconds. In the second block, we can see that the typical loop time is 40 nanoseconds, and the readings appear to have full nanosecond precision. Following the system clock results, the TSC clock source results are shown, in the same fashion. The <code class=\"command\">RDTSCP</code> instruction shows most loops completing in 20\u201330 nanoseconds, while the <code class=\"command\">RDTSC</code> instruction is the fastest with an average loop time of 20 nanoseconds. In this example the TSC clock source will be used by default, but can be disabled by setting <code class=\"varname\">timing_clock_source</code> to <code class=\"literal\">system</code>.</p>\n<pre class=\"screen\">System clock source: clock_gettime (CLOCK_MONOTONIC)\nTesting timing overhead for 3 seconds.\nAverage loop time including overhead: 44.67 ns\nHistogram of timing durations:\n   &lt;= ns   % of total  running %      count\n       0       0.0000     0.0000          0\n       1       0.0000     0.0000          0\n       3       0.0000     0.0000          0\n       7       0.0000     0.0000          0\n      15       0.0000     0.0000          0\n      31      24.0606    24.0606    5385707\n      63      75.8342    99.8948   16974658\n     127       0.0900    99.9848      20143\n     255       0.0069    99.9917       1542\n     511       0.0014    99.9932        322\n    1023       0.0003    99.9935         68\n    2047       0.0001    99.9936         23\n    4095       0.0036    99.9972        813\n    8191       0.0018    99.9990        402\n   16383       0.0005    99.9995        120\n   32767       0.0001    99.9997         32\n   65535       0.0001    99.9998         24\n\nObserved timing durations up to 99.9900%:\n      ns   % of total  running %      count\n      29       3.6921     3.6921     826442\n      30      16.6755    20.3676    3732628\n      31       3.6930    24.0606     826637\n      40      75.7761    99.8368   16961658\n      41       0.0019    99.8387        431\n...\n     190       0.0003    99.9901         65\n...\n29657159       0.0000   100.0000          1\n\nClock source: RDTSCP\nAverage loop time including overhead: 37.32 ns\nHistogram of timing durations:\n   &lt;= ns   % of total  running %      count\n       0       0.0000     0.0000          0\n       1       0.0000     0.0000          0\n       3       0.0000     0.0000          0\n       7       0.0000     0.0000          0\n      15       0.0000     0.0000          0\n      31      99.9499    99.9499   26782299\n      63       0.0381    99.9880      10220\n     127       0.0008    99.9889        224\n     255       0.0052    99.9941       1403\n     511       0.0013    99.9954        340\n    1023       0.0001    99.9954         17\n    2047       0.0000    99.9955          7\n    4095       0.0021    99.9976        569\n    8191       0.0013    99.9989        357\n   16383       0.0005    99.9994        128\n   32767       0.0003    99.9996         70\n   65535       0.0001    99.9997         19\n\nObserved timing durations up to 99.9900%:\n      ns   % of total  running %      count\n      20      16.9064    16.9064    4530201\n      29      41.5214    58.4279   11125972\n      30      41.5220    99.9499   11126126\n      40       0.0089    99.9587       2374\n...\n     130       0.0007    99.9902        181\n...\n18501572       0.0000   100.0000          1\n\nFast clock source: RDTSC\nAverage loop time including overhead: 27.12 ns\nHistogram of timing durations:\n   &lt;= ns   % of total  running %      count\n       0       0.0000     0.0000          0\n       1       0.0000     0.0000          0\n       3       0.0000     0.0000          0\n       7       0.0000     0.0000          0\n      15       1.2247     1.2247     456231\n      31      98.7566    99.9813   36789785\n      63       0.0109    99.9921       4049\n     127       0.0029    99.9951       1087\n     255       0.0008    99.9959        305\n     511       0.0007    99.9966        279\n    1023       0.0000    99.9966          7\n    2047       0.0001    99.9967         22\n    4095       0.0018    99.9985        673\n    8191       0.0010    99.9995        383\n   16383       0.0003    99.9998         94\n   32767       0.0001    99.9999         38\n   65535       0.0000    99.9999          9\n\nObserved timing durations up to 99.9900%:\n      ns   % of total  running %      count\n       9       0.6316     0.6316     235290\n      10       0.5931     1.2247     220941\n      20      91.4328    92.6574   34061442\n      29       3.6427    96.3001    1357007\n      30       3.6811    99.9813    1371336\n      40       0.0089    99.9902       3325\n...\n61594291       0.0000   100.0000          1\n\nTSC frequency source: x86, cpuid 0x15\nTSC frequency in use: 2449228 kHz\nTSC frequency from calibration: 2448603 kHz\n\nTSC clock source will be used by default, unless timing_clock_source is set to 'system'.\n</pre>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.8\">\n<h2>See Also</h2><span class=\"simplelist\"><a class=\"xref\" href=\"/docs/19/sql-explain.html\" title=\"EXPLAIN\"><span class=\"refentrytitle\">EXPLAIN</span></a>, <a class=\"xref\" href=\"/docs/19/runtime-config-resource.html#GUC-TIMING-CLOCK-SOURCE\">timing_clock_source</a>, <a class=\"ulink\" href=\"https://wiki.postgresql.org/wiki/Pg_test_timing\">Wiki discussion about timing</a></span>\n</div>\n</div></div>", "manual_path": "pgtesttiming.html", "comparison_data": {"options": [{"names": ["-c cutoff", "--cutoff= cutoff"], "signature": "-c cutoff --cutoff= cutoff", "description": "Specifies the cutoff percentage for the list of exact observed timing durations (that is, the changes in the system clock value from one reading to the next). The list will end once the running percentage total reaches or exceeds this value, except that the largest observed duration will always be printed. The default cutoff is 99.99."}, {"names": ["-d duration", "--duration= duration"], "signature": "-d duration --duration= duration", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "signature": "-V --version", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "signature": "-? --help", "description": "Show help about pg_test_timing command line arguments, and exit."}], "synopsis": ["pg_test_timing [ option ...]"], "environment": []}, "comparison_hash": "be611164318cc707ee6f510dff66f3aacece41205f98114e61d95b161b44fd10"}, "20": {"facts": [{"label": "Documented executable", "value": "pg_test_timing"}, {"label": "Executable version", "value": "20devel"}, {"label": "Reference inventory", "value": "Server applications"}, {"label": "Option definition groups", "value": "4"}], "tables": [{"key": "options", "rows": [{"summary": "Specifies the cutoff percentage for the list of exact observed timing durations (that is, the changes in the system clock value from one reading to the next). The list will end once the running percentage total reaches or exceeds this value, except that the largest observed duration will always be printed. The default cutoff is 99.99.", "signature": {"url": "/docs/devel/pgtesttiming.html", "text": "-c cutoff --cutoff= cutoff"}}, {"summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": {"url": "/docs/devel/pgtesttiming.html", "text": "-d duration --duration= duration"}}, {"summary": "Print the pg_test_timing version and exit.", "signature": {"url": "/docs/devel/pgtesttiming.html", "text": "-V --version"}}, {"summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": {"url": "/docs/devel/pgtesttiming.html", "text": "-? --help"}}], "title": "Documented options", "columns": [{"key": "signature", "label": "Option and arguments"}, {"key": "summary", "label": "Description"}]}], "options": [{"names": ["-c cutoff", "--cutoff= cutoff"], "summary": "Specifies the cutoff percentage for the list of exact observed timing durations (that is, the changes in the system clock value from one reading to the next). The list will end once the running percentage total reaches or exceeds this value, except that the largest observed duration will always be printed. The default cutoff is 99.99.", "signature": "-c cutoff --cutoff= cutoff", "source_url": "/docs/devel/pgtesttiming.html", "description": "Specifies the cutoff percentage for the list of exact observed timing durations (that is, the changes in the system clock value from one reading to the next). The list will end once the running percentage total reaches or exceeds this value, except that the largest observed duration will always be printed. The default cutoff is 99.99."}, {"names": ["-d duration", "--duration= duration"], "summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": "-d duration --duration= duration", "source_url": "/docs/devel/pgtesttiming.html", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "summary": "Print the pg_test_timing version and exit.", "signature": "-V --version", "source_url": "/docs/devel/pgtesttiming.html", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": "-? --help", "source_url": "/docs/devel/pgtesttiming.html", "description": "Show help about pg_test_timing command line arguments, and exit."}], "related": [], "release": {"ref": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "label": "20devel", "major": "20", "channel": "devel", "manifest": {"pdf": {"A4": {"url": "/files/documentation/pdf/20/postgresql-20-A4.pdf", "bytes": 16030631, "pages": 3052, "sha256": "bd5d82c0ce38fc18f92a0447818a91a193a261776bca1c37564bf9a683e177d0", "built_at": "2026-09-28"}, "US": {"url": "/files/documentation/pdf/20/postgresql-20-US.pdf", "bytes": 15936613, "pages": 3223, "sha256": "d97d9e0db479a02f4234b175f50fcad70c3661619afc8d6df9b9437882e3c299", "built_at": "2026-09-28"}}, "tree": "0", "index": "index.html", "major": "20", "pages": 1156, "release": "20devel", "source_url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "svg_assets": 6, "source_mode": "en SGML built with pinned official archive", "source_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41", "source_snapshot_utc": "26-Sep-2026 20:22"}, "revision": "2eba5e0fd4c3bffb2803247b6cd537878e9d6ee5a6dfbe3c50ece8b421b80918", "evidence_kind": "English manual and source declarations", "source_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}, "sources": [{"url": "/docs/devel/pgtesttiming.html", "file": "pgtesttiming.html", "label": "20devel English manual \u00b7 pgtesttiming.html", "anchor": "", "sha256": "e7897e7aa40e1ca8db62e75e33493c2f3a8c168bf377dd63f1702baaa9af4977"}, {"url": "/docs/devel/reference-server.html", "file": "reference-server.html", "label": "Server applications inventory", "anchor": "", "sha256": "5532c1ebfb8c6f310301be63a28daf0ae212e2a78025bea61a1bdca99e02c43d"}], "sections": [], "synopsis": ["pg_test_timing [ option ...]"], "signature": "pg_test_timing [ option ...]", "description": ["pg_test_timing \u2014 measure timing overhead"], "environment": [], "manual_html": "<div><div class=\"refentry\" id=\"PGTESTTIMING\">\n<div class=\"titlepage\"></div>\n<div class=\"refnamediv\">\n<h2><span class=\"refentrytitle\"><span class=\"application\">pg_test_timing</span></span></h2>\n<p>pg_test_timing \u2014 measure timing overhead</p>\n</div>\n<div class=\"refsynopsisdiv\">\n<h2>Synopsis</h2>\n<div class=\"cmdsynopsis\">\n<p id=\"id-1.9.5.12.4.1\"><code class=\"command\">pg_test_timing</code> [<em class=\"replaceable\"><code>option</code></em>...]</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.5\">\n<h2>Description</h2>\n<p><span class=\"application\">pg_test_timing</span> is a tool to measure the timing overhead on your system and confirm that the system time never moves backwards. It reads supported clock sources over and over again as fast as it can for a specified length of time, and then prints statistics about the observed differences in successive clock readings, as well as which clock source will be used.</p>\n<p>Smaller (but not zero) differences are better, since they imply both more-precise clock hardware and less overhead to collect a clock reading. Systems that are slow to collect timing data can give less accurate <code class=\"command\">EXPLAIN ANALYZE</code> results.</p>\n<p>This tool is also helpful to determine if the <code class=\"varname\">track_io_timing</code> configuration parameter is likely to produce useful results, and whether the TSC clock source (see <a class=\"xref\" href=\"/docs/devel/runtime-config-resource.html#GUC-TIMING-CLOCK-SOURCE\">timing_clock_source</a>) is available and if it will be used by default.</p>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.6\">\n<h2>Options</h2>\n<p><span class=\"application\">pg_test_timing</span> accepts the following command-line options:</p>\n<div class=\"variablelist\">\n<dl class=\"variablelist\">\n<dt><span class=\"term\"><code class=\"option\">-c <em class=\"replaceable\"><code>cutoff</code></em></code><br></span><span class=\"term\"><code class=\"option\">--cutoff=<em class=\"replaceable\"><code>cutoff</code></em></code></span></dt>\n<dd>\n<p>Specifies the cutoff percentage for the list of exact observed timing durations (that is, the changes in the system clock value from one reading to the next). The list will end once the running percentage total reaches or exceeds this value, except that the largest observed duration will always be printed. The default cutoff is 99.99.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-d <em class=\"replaceable\"><code>duration</code></em></code><br></span><span class=\"term\"><code class=\"option\">--duration=<em class=\"replaceable\"><code>duration</code></em></code></span></dt>\n<dd>\n<p>Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-V</code><br></span><span class=\"term\"><code class=\"option\">--version</code></span></dt>\n<dd>\n<p>Print the <span class=\"application\">pg_test_timing</span> version and exit.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-?</code><br></span><span class=\"term\"><code class=\"option\">--help</code></span></dt>\n<dd>\n<p>Show help about <span class=\"application\">pg_test_timing</span> command line arguments, and exit.</p>\n</dd>\n</dl>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.7\">\n<h2>Usage</h2>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.2\">\n<h3>Interpreting Results</h3>\n<p>The first block of output has four columns, with rows showing a shifted-by-one log2(ns) histogram of timing durations (that is, the differences between successive clock readings). This is not the classic log2(n+1) histogram as it counts zeros separately and then switches to log2(ns) starting from value 1.</p>\n<p>The columns are:</p>\n<div class=\"itemizedlist\">\n<ul class=\"itemizedlist compact\">\n<li class=\"listitem\">nanosecond value that is &gt;= the durations in this bucket</li>\n<li class=\"listitem\">percentage of durations in this bucket</li>\n<li class=\"listitem\">running-sum percentage of durations in this and previous buckets</li>\n<li class=\"listitem\">count of durations in this bucket</li>\n</ul>\n</div>\n<p>The second block of output goes into more detail, showing the exact timing differences observed. For brevity this list is cut off when the running-sum percentage exceeds the user-selectable cutoff value. However, the largest observed difference is always shown.</p>\n<p>On platforms that support the TSC clock source, additional output sections are shown for the <code class=\"command\">RDTSCP</code> instruction (used for general timing needs, such as <code class=\"varname\">track_io_timing</code>) and the <code class=\"command\">RDTSC</code> instruction (used for <code class=\"command\">EXPLAIN ANALYZE</code>). At the end of the output, the TSC frequency, which may either be sourced from CPU information directly, or the alternate calibration mechanism are shown, as well as whether the TSC clock source will be used by default.</p>\n<p>The example results below show system clock timing where 99.99% of loops took between 16 and 63 nanoseconds. In the second block, we can see that the typical loop time is 40 nanoseconds, and the readings appear to have full nanosecond precision. Following the system clock results, the TSC clock source results are shown, in the same fashion. The <code class=\"command\">RDTSCP</code> instruction shows most loops completing in 20\u201330 nanoseconds, while the <code class=\"command\">RDTSC</code> instruction is the fastest with an average loop time of 20 nanoseconds. In this example the TSC clock source will be used by default, but can be disabled by setting <code class=\"varname\">timing_clock_source</code> to <code class=\"literal\">system</code>.</p>\n<pre class=\"screen\">System clock source: clock_gettime (CLOCK_MONOTONIC)\nTesting timing overhead for 3 seconds.\nAverage loop time including overhead: 44.67 ns\nHistogram of timing durations:\n   &lt;= ns   % of total  running %      count\n       0       0.0000     0.0000          0\n       1       0.0000     0.0000          0\n       3       0.0000     0.0000          0\n       7       0.0000     0.0000          0\n      15       0.0000     0.0000          0\n      31      24.0606    24.0606    5385707\n      63      75.8342    99.8948   16974658\n     127       0.0900    99.9848      20143\n     255       0.0069    99.9917       1542\n     511       0.0014    99.9932        322\n    1023       0.0003    99.9935         68\n    2047       0.0001    99.9936         23\n    4095       0.0036    99.9972        813\n    8191       0.0018    99.9990        402\n   16383       0.0005    99.9995        120\n   32767       0.0001    99.9997         32\n   65535       0.0001    99.9998         24\n\nObserved timing durations up to 99.9900%:\n      ns   % of total  running %      count\n      29       3.6921     3.6921     826442\n      30      16.6755    20.3676    3732628\n      31       3.6930    24.0606     826637\n      40      75.7761    99.8368   16961658\n      41       0.0019    99.8387        431\n...\n     190       0.0003    99.9901         65\n...\n29657159       0.0000   100.0000          1\n\nClock source: RDTSCP\nAverage loop time including overhead: 37.32 ns\nHistogram of timing durations:\n   &lt;= ns   % of total  running %      count\n       0       0.0000     0.0000          0\n       1       0.0000     0.0000          0\n       3       0.0000     0.0000          0\n       7       0.0000     0.0000          0\n      15       0.0000     0.0000          0\n      31      99.9499    99.9499   26782299\n      63       0.0381    99.9880      10220\n     127       0.0008    99.9889        224\n     255       0.0052    99.9941       1403\n     511       0.0013    99.9954        340\n    1023       0.0001    99.9954         17\n    2047       0.0000    99.9955          7\n    4095       0.0021    99.9976        569\n    8191       0.0013    99.9989        357\n   16383       0.0005    99.9994        128\n   32767       0.0003    99.9996         70\n   65535       0.0001    99.9997         19\n\nObserved timing durations up to 99.9900%:\n      ns   % of total  running %      count\n      20      16.9064    16.9064    4530201\n      29      41.5214    58.4279   11125972\n      30      41.5220    99.9499   11126126\n      40       0.0089    99.9587       2374\n...\n     130       0.0007    99.9902        181\n...\n18501572       0.0000   100.0000          1\n\nFast clock source: RDTSC\nAverage loop time including overhead: 27.12 ns\nHistogram of timing durations:\n   &lt;= ns   % of total  running %      count\n       0       0.0000     0.0000          0\n       1       0.0000     0.0000          0\n       3       0.0000     0.0000          0\n       7       0.0000     0.0000          0\n      15       1.2247     1.2247     456231\n      31      98.7566    99.9813   36789785\n      63       0.0109    99.9921       4049\n     127       0.0029    99.9951       1087\n     255       0.0008    99.9959        305\n     511       0.0007    99.9966        279\n    1023       0.0000    99.9966          7\n    2047       0.0001    99.9967         22\n    4095       0.0018    99.9985        673\n    8191       0.0010    99.9995        383\n   16383       0.0003    99.9998         94\n   32767       0.0001    99.9999         38\n   65535       0.0000    99.9999          9\n\nObserved timing durations up to 99.9900%:\n      ns   % of total  running %      count\n       9       0.6316     0.6316     235290\n      10       0.5931     1.2247     220941\n      20      91.4328    92.6574   34061442\n      29       3.6427    96.3001    1357007\n      30       3.6811    99.9813    1371336\n      40       0.0089    99.9902       3325\n...\n61594291       0.0000   100.0000          1\n\nTSC frequency source: x86, cpuid 0x15\nTSC frequency in use: 2449228 kHz\nTSC frequency from calibration: 2448603 kHz\n\nTSC clock source will be used by default, unless timing_clock_source is set to 'system'.\n</pre>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.8\">\n<h2>See Also</h2><span class=\"simplelist\"><a class=\"xref\" href=\"/docs/devel/sql-explain.html\" title=\"EXPLAIN\"><span class=\"refentrytitle\">EXPLAIN</span></a>, <a class=\"xref\" href=\"/docs/devel/runtime-config-resource.html#GUC-TIMING-CLOCK-SOURCE\">timing_clock_source</a>, <a class=\"ulink\" href=\"https://wiki.postgresql.org/wiki/Pg_test_timing\">Wiki discussion about timing</a></span>\n</div>\n</div></div>", "manual_path": "pgtesttiming.html", "comparison_data": {"options": [{"names": ["-c cutoff", "--cutoff= cutoff"], "signature": "-c cutoff --cutoff= cutoff", "description": "Specifies the cutoff percentage for the list of exact observed timing durations (that is, the changes in the system clock value from one reading to the next). The list will end once the running percentage total reaches or exceeds this value, except that the largest observed duration will always be printed. The default cutoff is 99.99."}, {"names": ["-d duration", "--duration= duration"], "signature": "-d duration --duration= duration", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "signature": "-V --version", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "signature": "-? --help", "description": "Show help about pg_test_timing command line arguments, and exit."}], "synopsis": ["pg_test_timing [ option ...]"], "environment": []}, "comparison_hash": "be611164318cc707ee6f510dff66f3aacece41205f98114e61d95b161b44fd10"}}}, "snapshot": {"facts": [{"label": "Documented executable", "value": "pg_test_timing"}, {"label": "Executable version", "value": "18.6"}, {"label": "Reference inventory", "value": "Server applications"}, {"label": "Option definition groups", "value": "3"}], "tables": [{"key": "options", "rows": [{"summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": {"url": "/docs/18/pgtesttiming.html", "text": "-d duration --duration= duration"}}, {"summary": "Print the pg_test_timing version and exit.", "signature": {"url": "/docs/18/pgtesttiming.html", "text": "-V --version"}}, {"summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": {"url": "/docs/18/pgtesttiming.html", "text": "-? --help"}}], "title": "Documented options", "columns": [{"key": "signature", "label": "Option and arguments"}, {"key": "summary", "label": "Description"}]}], "options": [{"names": ["-d duration", "--duration= duration"], "summary": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.", "signature": "-d duration --duration= duration", "source_url": "/docs/18/pgtesttiming.html", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "summary": "Print the pg_test_timing version and exit.", "signature": "-V --version", "source_url": "/docs/18/pgtesttiming.html", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "summary": "Show help about pg_test_timing command line arguments, and exit.", "signature": "-? --help", "source_url": "/docs/18/pgtesttiming.html", "description": "Show help about pg_test_timing command line arguments, and exit."}], "related": [], "release": {"ref": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "label": "18.6", "major": "18", "channel": "stable", "manifest": {"pdf": {"A4": {"url": "/files/documentation/pdf/18/postgresql-18-A4.pdf", "bytes": 15865106, "pages": 3154, "sha256": "19512c405da53f9f7fcf0abba359223aa65f021be025bf3411381918f92e3190", "built_at": "2026-09-26"}, "US": {"url": "/files/documentation/pdf/18/postgresql-18-US.pdf", "bytes": 15748059, "pages": 3328, "sha256": "facbe6c229e598b872d3d98bef53308f46e06746006fa4590de9a7de9dd46319", "built_at": "2026-09-26"}}, "tree": "18", "index": "index.html", "major": "18", "pages": 1148, "release": "18.6", "source_url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "svg_assets": 3, "source_mode": "en SGML built with pinned official archive", "source_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, "revision": "ee8d1a3612338fd9adf250730cb640fcc5233b5491337cc00a316a44e3a0b9f8", "evidence_kind": "English manual and source declarations", "source_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, "sources": [{"url": "/docs/18/pgtesttiming.html", "file": "pgtesttiming.html", "label": "18.6 English manual \u00b7 pgtesttiming.html", "anchor": "", "sha256": "8766dacb1c3fc7b8afd518c8cf1165ac81c82eef9375dc6d3e1a7ae2e99962f5"}, {"url": "/docs/18/reference-server.html", "file": "reference-server.html", "label": "Server applications inventory", "anchor": "", "sha256": "e9f8bbcc8e3641fadd1d20991e8aad6b532155b786ba5a1b7b364ec4f1a5bef3"}], "sections": [], "synopsis": ["pg_test_timing [ option ...]"], "signature": "pg_test_timing [ option ...]", "description": ["pg_test_timing \u2014 measure timing overhead"], "environment": [], "manual_html": "<div><div class=\"refentry\" id=\"PGTESTTIMING\">\n<div class=\"titlepage\"></div>\n<div class=\"refnamediv\">\n<h2><span class=\"refentrytitle\"><span class=\"application\">pg_test_timing</span></span></h2>\n<p>pg_test_timing \u2014 measure timing overhead</p>\n</div>\n<div class=\"refsynopsisdiv\">\n<h2>Synopsis</h2>\n<div class=\"cmdsynopsis\">\n<p id=\"id-1.9.5.12.4.1\"><code class=\"command\">pg_test_timing</code> [<em class=\"replaceable\"><code>option</code></em>...]</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.5\">\n<h2>Description</h2>\n<p><span class=\"application\">pg_test_timing</span> is a tool to measure the timing overhead on your system and confirm that the system time never moves backwards. Systems that are slow to collect timing data can give less accurate <code class=\"command\">EXPLAIN ANALYZE</code> results.</p>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.6\">\n<h2>Options</h2>\n<p><span class=\"application\">pg_test_timing</span> accepts the following command-line options:</p>\n<div class=\"variablelist\">\n<dl class=\"variablelist\">\n<dt><span class=\"term\"><code class=\"option\">-d <em class=\"replaceable\"><code>duration</code></em></code><br></span><span class=\"term\"><code class=\"option\">--duration=<em class=\"replaceable\"><code>duration</code></em></code></span></dt>\n<dd>\n<p>Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-V</code><br></span><span class=\"term\"><code class=\"option\">--version</code></span></dt>\n<dd>\n<p>Print the <span class=\"application\">pg_test_timing</span> version and exit.</p>\n</dd>\n<dt><span class=\"term\"><code class=\"option\">-?</code><br></span><span class=\"term\"><code class=\"option\">--help</code></span></dt>\n<dd>\n<p>Show help about <span class=\"application\">pg_test_timing</span> command line arguments, and exit.</p>\n</dd>\n</dl>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.7\">\n<h2>Usage</h2>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.2\">\n<h3>Interpreting Results</h3>\n<p>Good results will show most (&gt;90%) individual timing calls take less than one microsecond. Average per loop overhead will be even lower, below 100 nanoseconds. This example from an Intel i7-860 system using a TSC clock source shows excellent performance:</p>\n<pre class=\"screen\">Testing timing overhead for 3 seconds.\nPer loop time including overhead: 35.96 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     96.40465   80435604\n     2      3.59518    2999652\n     4      0.00015        126\n     8      0.00002         13\n    16      0.00000          2\n</pre>\n<p>Note that different units are used for the per loop time than the histogram. The loop can have resolution within a few nanoseconds (ns), while the individual timing calls can only resolve down to one microsecond (us).</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.3\">\n<h3>Measuring Executor Timing Overhead</h3>\n<p>When the query executor is running a statement using <code class=\"command\">EXPLAIN ANALYZE</code>, individual operations are timed as well as showing a summary. The overhead of your system can be checked by counting rows with the <span class=\"application\">psql</span> program:</p>\n<pre class=\"screen\">CREATE TABLE t AS SELECT * FROM generate_series(1,100000);\n\\timing\nSELECT COUNT(*) FROM t;\nEXPLAIN ANALYZE SELECT COUNT(*) FROM t;\n</pre>\n<p>The i7-860 system measured runs the count query in 9.8 ms while the <code class=\"command\">EXPLAIN ANALYZE</code> version takes 16.6 ms, each processing just over 100,000 rows. That 6.8 ms difference means the timing overhead per row is 68 ns, about twice what pg_test_timing estimated it would be. Even that relatively small amount of overhead is making the fully timed count statement take almost 70% longer. On more substantial queries, the timing overhead would be less problematic.</p>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.4\">\n<h3>Changing Time Sources</h3>\n<p>On some newer Linux systems, it's possible to change the clock source used to collect timing data at any time. A second example shows the slowdown possible from switching to the slower acpi_pm time source, on the same system used for the fast results above:</p>\n<pre class=\"screen\"># cat /sys/devices/system/clocksource/clocksource0/available_clocksource\ntsc hpet acpi_pm\n# echo acpi_pm &gt; /sys/devices/system/clocksource/clocksource0/current_clocksource\n# pg_test_timing\nPer loop time including overhead: 722.92 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     27.84870    1155682\n     2     72.05956    2990371\n     4      0.07810       3241\n     8      0.01357        563\n    16      0.00007          3\n</pre>\n<p>In this configuration, the sample <code class=\"command\">EXPLAIN ANALYZE</code> above takes 115.9 ms. That's 1061 ns of timing overhead, again a small multiple of what's measured directly by this utility. That much timing overhead means the actual query itself is only taking a tiny fraction of the accounted for time, most of it is being consumed in overhead instead. In this configuration, any <code class=\"command\">EXPLAIN ANALYZE</code> totals involving many timed operations would be inflated significantly by timing overhead.</p>\n<p>FreeBSD also allows changing the time source on the fly, and it logs information about the timer selected during boot:</p>\n<pre class=\"screen\"># dmesg | grep \"Timecounter\"\nTimecounter \"ACPI-fast\" frequency 3579545 Hz quality 900\nTimecounter \"i8254\" frequency 1193182 Hz quality 0\nTimecounters tick every 10.000 msec\nTimecounter \"TSC\" frequency 2531787134 Hz quality 800\n# sysctl kern.timecounter.hardware=TSC\nkern.timecounter.hardware: ACPI-fast -&gt; TSC\n</pre>\n<p>Other systems may only allow setting the time source on boot. On older Linux systems the \"clock\" kernel setting is the only way to make this sort of change. And even on some more recent ones, the only option you'll see for a clock source is \"jiffies\". Jiffies are the older Linux software clock implementation, which can have good resolution when it's backed by fast enough timing hardware, as in this example:</p>\n<pre class=\"screen\">$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource\njiffies\n$ dmesg | grep time.c\ntime.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.\ntime.c: Detected 2400.153 MHz processor.\n$ pg_test_timing\nTesting timing overhead for 3 seconds.\nPer timing duration including loop overhead: 97.75 ns\nHistogram of timing durations:\n  &lt; us   % of total      count\n     1     90.23734   27694571\n     2      9.75277    2993204\n     4      0.00981       3010\n     8      0.00007         22\n    16      0.00000          1\n    32      0.00000          1\n</pre>\n</div>\n<div class=\"refsect2\" id=\"id-1.9.5.12.7.5\">\n<h3>Clock Hardware and Timing Accuracy</h3>\n<p>Collecting accurate timing information is normally done on computers using hardware clocks with various levels of accuracy. With some hardware the operating systems can pass the system clock time almost directly to programs. A system clock can also be derived from a chip that simply provides timing interrupts, periodic ticks at some known time interval. In either case, operating system kernels provide a clock source that hides these details. But the accuracy of that clock source and how quickly it can return results varies based on the underlying hardware.</p>\n<p>Inaccurate time keeping can result in system instability. Test any change to the clock source very carefully. Operating system defaults are sometimes made to favor reliability over best accuracy. And if you are using a virtual machine, look into the recommended time sources compatible with it. Virtual hardware faces additional difficulties when emulating timers, and there are often per operating system settings suggested by vendors.</p>\n<p>The Time Stamp Counter (TSC) clock source is the most accurate one available on current generation CPUs. It's the preferred way to track the system time when it's supported by the operating system and the TSC clock is reliable. There are several ways that TSC can fail to provide an accurate timing source, making it unreliable. Older systems can have a TSC clock that varies based on the CPU temperature, making it unusable for timing. Trying to use TSC on some older multicore CPUs can give a reported time that's inconsistent among multiple cores. This can result in the time going backwards, a problem this program checks for. And even the newest systems can fail to provide accurate TSC timing with very aggressive power saving configurations.</p>\n<p>Newer operating systems may check for the known TSC problems and switch to a slower, more stable clock source when they are seen. If your system supports TSC time but doesn't default to that, it may be disabled for a good reason. And some operating systems may not detect all the possible problems correctly, or will allow using TSC even in situations where it's known to be inaccurate.</p>\n<p>The High Precision Event Timer (HPET) is the preferred timer on systems where it's available and TSC is not accurate. The timer chip itself is programmable to allow up to 100 nanosecond resolution, but you may not see that much accuracy in your system clock.</p>\n<p>Advanced Configuration and Power Interface (ACPI) provides a Power Management (PM) Timer, which Linux refers to as the acpi_pm. The clock derived from acpi_pm will at best provide 300 nanosecond resolution.</p>\n<p>Timers used on older PC hardware include the 8254 Programmable Interval Timer (PIT), the real-time clock (RTC), the Advanced Programmable Interrupt Controller (APIC) timer, and the Cyclone timer. These timers aim for millisecond resolution.</p>\n</div>\n</div>\n<div class=\"refsect1\" id=\"id-1.9.5.12.8\">\n<h2>See Also</h2><span class=\"simplelist\"><a class=\"xref\" href=\"/docs/18/sql-explain.html\" title=\"EXPLAIN\"><span class=\"refentrytitle\">EXPLAIN</span></a></span>\n</div>\n</div></div>", "manual_path": "pgtesttiming.html", "comparison_data": {"options": [{"names": ["-d duration", "--duration= duration"], "signature": "-d duration --duration= duration", "description": "Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds."}, {"names": ["-V", "--version"], "signature": "-V --version", "description": "Print the pg_test_timing version and exit."}, {"names": ["-?", "--help"], "signature": "-? --help", "description": "Show help about pg_test_timing command line arguments, and exit."}], "synopsis": ["pg_test_timing [ option ...]"], "environment": []}, "comparison_hash": "1e9850049374c38671166c0a5cf0759d6f33dd01f733985211c9962ac16213b4"}, "comparison": {"left": "18", "right": "19", "status": "changed", "diff": "--- PostgreSQL 18\n+++ PostgreSQL 19\n@@ -1,6 +1,14 @@\n {\n   \"environment\": [],\n   \"options\": [\n+    {\n+      \"description\": \"Specifies the cutoff percentage for the list of exact observed timing durations (that is, the changes in the system clock value from one reading to the next). The list will end once the running percentage total reaches or exceeds this value, except that the largest observed duration will always be printed. The default cutoff is 99.99.\",\n+      \"names\": [\n+        \"-c cutoff\",\n+        \"--cutoff= cutoff\"\n+      ],\n+      \"signature\": \"-c cutoff --cutoff= cutoff\"\n+    },\n     {\n       \"description\": \"Specifies the test duration, in seconds. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards. The default test duration is 3 seconds.\",\n       \"names\": ["}}