You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Correct the readme, and picture the settings panel
Some of what the readme said had drifted from what the program does. It named
the reason a server wins a Best-of round as `fastest`, which nothing reports -
it is `fastest_ranked`. It put the power switch in the row of tabs, when it
sits beside them in the top bar. It listed some of the columns the exported
spreadsheet ends with and not others, so anyone opening a file found five
columns the readme never mentioned. It explained the export's version number
without saying that turning Discard losers off is what moves it. And it never
named the server the bufferbloat test pings - one.one.one.one - a call the
"who does Pingularity talk to" table was missing as well. One more address the
dashboard uses, /api/speedtest/candidates, was absent from the list of calls
that carry no body.
The pictures were behind in two ways. The themes picture showed six themes when
there are nine, leaving out Parchment, Solarized and Ember; it now shows all
nine. And nothing pictured the settings panel, which is where most of the
readme's second half happens, so there is a shot of it now, open on the Ookla
tab with the server list, the Best-of controls and the saved servers.
The descriptions attached to each picture for people who cannot see them were
written for older versions of those pictures and now match what is in them. The
dashboard picture also stops describing itself as the live demo, which it is
not.
Co-Authored-By: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+29-19Lines changed: 29 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,9 +10,10 @@ by majority vote (a *quorum* across multiple *anchors*), with anti-flapping
10
10
latency, uptime, and speed to SQLite and shows it all in a live UI - no runtime
11
11
to install.
12
12
13
-
This is the [live demo](https://demo.pingularity.dev) - same dashboard, synthetic data:
13
+
This is the dashboard on a real install. The [live demo](https://demo.pingularity.dev)
14
+
is the same thing on synthetic data, with a badge to say so:
14
15
15
-

16
+

16
17
17
18
## Quick start
18
19
@@ -454,7 +455,11 @@ published.
454
455
> are down: any run carrying the new columns stamps the export for the release
455
456
> that introduced them - 0.70 for the failed-run marker, higher again for the
456
457
> city-race verdict every Ookla run has recorded since - and an older build
457
-
> refuses a newer stamp outright rather than restoring half of it.
458
+
> refuses a newer stamp outright rather than restoring half of it. One rung is
459
+
> yours to trigger: with **Discard losers** off a round's other servers are kept
460
+
> as rows of their own, which stamps the export a rung higher again, so take the
461
+
> backup before you turn it off (or turn it back on first) if the file has to
462
+
> restore onto an older release.
458
463
459
464
## Run in the background (systemd / launchd / Windows service)
460
465
@@ -670,13 +675,13 @@ transfer, reported as their **median** (if none of them land, iperf3's own
670
675
`min_rtt`, and failing that the idle baseline). There is no separate fastest
671
676
figure on those runs, so that median is both what is shown and what decides.
672
677
673
-

678
+

674
679
675
680
**Bufferbloat** is the extra lag that appears only while the line is busy - the
676
681
reason a video call breaks up the moment a big download starts. Pingularity
677
682
measures it by pinging before the test (idle) and during it (loaded) - both
678
-
against a fixed target of its own rather than the speedtest server, so only the
679
-
gap between them is meaningful, and the idle figure will not match the **ping**
683
+
against a fixed target of its own (`one.one.one.one`, Cloudflare) rather than
684
+
the speedtest server, so only the gap between them is meaningful, and the idle figure will not match the **ping**
680
685
recorded above:
681
686
682
687
```mermaid
@@ -942,7 +947,7 @@ rather than by jitter: a run **keeps the server the last automatic run
942
947
measured**while it is still among the servers this run pings (the winning
943
948
city's list, seeded as above) and still pings within max(2 ms, 15 %) of the
944
949
fastest (win reason `incumbent` when that kept it ahead of a faster server;
945
-
plain `fastest` when it was the fastest anyway), and failing that prefers your
950
+
plain `fastest_ranked` when it was the fastest anyway), and failing that prefers your
946
951
ISP's own server inside the same band (`on_net`) - so the history compares
947
952
like with like instead of flipping between equivalent servers, while a server
948
953
that has gone bad loses its seat the run it goes bad, because the seat is
@@ -1154,6 +1159,7 @@ Below that:
1154
1159
>|**RIPE IPmap**| the two boundary router IPs the traceroute settles on, and your resolver's egress address, for geolocation | connection refresh + exit discovery |
1155
1160
> | **ipwho.is**, then **geojs.io** | your public IP, for the ISP/geo line | connection refresh |
1156
1161
> | **Cloudflare** (`/cdn-cgi/trace`) | a plain fetch, to learn the serving PoP | connection refresh |
1162
+
> | **one.one.one.one:443** (Cloudflare) | bare TCP handshakes, no payload - the fixed target the bufferbloat idle and loaded samples are measured against. Resolved through your own resolver, so it reaches whichever of `1.1.1.1`/`1.0.0.1` (or their v6 pair) that answer names | every speedtest that samples bufferbloat |
1157
1163
> | reverse DNS | router/host IPs, for names | connection refresh |
1158
1164
> | **Ookla** servers | the speedtest traffic itself, plus a server-list lookup and a small probe of each listed server's upload endpoint (remembered, so a repeat does not send it again); opening the Ookla tab can also cost one by-ID lookup and one name search first, to centre the list on the server your last automatic run used; for the picker's Auto button, the same selection a run performs - one list fetch per candidate city, a round of pings at every racer, then a round at the rest of the winning city's field (up to twelve), no transfer; for a server ID typed in Find, and for a saved pin the drawer has not yet checked this page load (at most twice per server), one by-ID lookup plus one small POST at that server's upload endpoint to learn whether it can still run a test, no transfer; and for the saved list's refresh button, one by-ID lookup, one endpoint probe and a round of pings at each kept server (up to twelve), no transfer | when a speedtest runs, when the Ookla settings tab is opened or a city is searched, when a server ID is typed in Find or a saved pin is first shown, on every Auto click, and on every refresh click in the saved list |
1159
1165
> | your own **iperf3 server** (opt-in) | the test traffic itself - the TCP transfers, plus a short UDP pass for loss and jitter; or, for the status light in the settings drawer, one bare TCP handshake and nothing else | when an iperf3 speedtest runs, and when the drawer checks a saved server's status light - once per address while the drawer is open with iperf3 selected, plus whenever you click a server's light or change its address |
The **logo** (top-right) opens a tabbed settings drawer; a **power** toggle in
1223
-
the tab row starts/stops all monitoring. Changes apply **live** (no restart)
1224
-
and persist across restarts:
1228
+
The **logo** (top-right) opens a tabbed settings drawer; the **power** toggle
1229
+
beside it, in the top bar, starts/stops all monitoring. Changes apply **live** (no restart)
1230
+
and persist across restarts.
1231
+
1232
+

sensitivity (failures→down / successes→up, IPv6 mode auto/on/off), plus the
@@ -1420,7 +1428,7 @@ and persist across restarts:
1420
1428
**Nine built-in themes**, every one fully recolourable (backgrounds, panels,
1421
1429
status colours, chart series - each picker previews live and resets to the theme):
1422
1430
1423
-

1431
+

1424
1432
1425
1433
>**Notifications** post to one webhook URL, shaped per host so the common
1426
1434
> targets just work - JSON everywhere except ntfy. Discord → `{content}`,
@@ -1925,8 +1933,8 @@ constant memory.
1925
1933
1926
1934
Every `POST` must carry `Content-Type: application/json`, **including the ones
1927
1935
with no body at all** (`/api/speedtest`, `/api/speedtest/abort`, `/api/netinfo`,
1928
-
`/api/iperf/check`, `/api/speedtest/servers`, `/api/auth/logout`), which answer
1929
-
`415` without it. It is a CSRF guard: a cross-site form cannot set that content
0 commit comments