{
  "schema_version": 3,
  "app": "adguard-home",
  "display_name": "AdGuard Home",
  "upstream_repo": "https://github.com/AdguardTeam/AdGuardHome",
  "docs_url": "https://github.com/AdguardTeam/AdGuardHome/wiki/Docker",
  "status": "ok",
  "summary": {
    "primary_service": "adguardhome",
    "app_version": "v0.107.79",
    "app_version_pinned": true,
    "runs": 3,
    "publishable": true,
    "publishable_note": null,
    "idle_total_mem_mib": 39.25,
    "idle_total_cpu_pct": 0.04,
    "peak_total_mem_mib": 61.37,
    "peak_is_under_load": true,
    "startup_seconds": 0.4,
    "startup_peak_total_mem_mib": 41.8,
    "settled": true,
    "settle_seconds_used": 120.9,
    "peak_max_mib": 61.53,
    "sizing_peak_mib": 61.53,
    "idle_mem_mib": {
      "median": 39.25,
      "min": 39.23,
      "max": 43.27,
      "values": [
        39.25,
        43.27,
        39.23
      ]
    },
    "idle_cpu_pct": {
      "median": 0.04,
      "min": 0.01,
      "max": 0.04,
      "values": [
        0.01,
        0.04,
        0.04
      ]
    },
    "peak_mem_mib": {
      "median": 61.37,
      "min": 59.47,
      "max": 61.53,
      "values": [
        59.47,
        61.53,
        61.37
      ]
    },
    "startup_peak_mem_mib": {
      "median": 41.8,
      "min": 41.41,
      "max": 45.82,
      "values": [
        41.41,
        45.82,
        41.8
      ]
    },
    "startup_s": {
      "median": 0.4,
      "min": 0.4,
      "max": 0.4,
      "values": [
        0.4,
        0.4,
        0.4
      ]
    },
    "settled_after_healthy_s": {
      "median": 122.4,
      "min": 122.4,
      "max": 124.5,
      "values": [
        124.5,
        122.4,
        122.4
      ]
    },
    "settled_runs": 3,
    "per_service": {
      "adguardhome": {
        "idle_mem_mib": {
          "median": 39.25,
          "min": 39.23,
          "max": 43.27,
          "values": [
            39.25,
            43.27,
            39.23
          ]
        },
        "peak_mem_mib": {
          "median": 61.37,
          "min": 59.47,
          "max": 61.53,
          "values": [
            59.47,
            61.53,
            61.37
          ]
        }
      }
    },
    "variance_flag": null,
    "representative_run": 1,
    "cpu_models": [
      "AMD EPYC 9V45 96-Core Processor"
    ],
    "cpu_model_mismatch": false,
    "rule": "idle = median of the run idle means; peak = median of the run peaks (highest simultaneous total, under load when the app has a load step); peak_max_mib = highest run peak; sizing_peak_mib = highest over runs of max(run peak, run startup peak); variance_flag when max/min over runs is above 1.5 for idle or peak."
  },
  "run": {
    "started_at": "2026-10-19T03:13:13Z",
    "date": "2026-10-19",
    "harness_version": "3.0.0",
    "runs_requested": 3,
    "docker_host": null,
    "remote": false,
    "runs_completed": 3
  },
  "host": {
    "label": "github-actions ubuntu-latest (2 vCPU, 8 GB)",
    "ci": {
      "runs_on": "ubuntu-latest",
      "runner_environment": "github-hosted",
      "runner_os": "Linux",
      "runner_arch": "X64",
      "image_os": "ubuntu24",
      "image_version": "20261012.334.1"
    },
    "cpu_model": "AMD EPYC 9V45 96-Core Processor",
    "cpu_model_note": null,
    "cores": 2,
    "mem_total_mib": 7938,
    "kernel": "6.17.0-1022-azure",
    "os": "Ubuntu 24.04.5 LTS",
    "arch": "x86_64",
    "oci_arch": "amd64",
    "docker_server_version": "28.0.4",
    "docker_client_version": "28.0.4",
    "compose_client_version": "2.38.2",
    "storage_driver": "overlay2",
    "containerd_image_store": false,
    "source": "docker info + throwaway container reading /proc/cpuinfo on the daemon host",
    "compose_note": "Compose runs on the client machine; Docker server fields are from the daemon host"
  },
  "helper_images": {
    "curlimages/curl:latest": {
      "pulled_as": "curlimages/curl:latest",
      "digest": "curlimages/curl@sha256:a134550be58ab783810e613ae96fd253c38f7bdd16d9bf9be350700c7a29ac06"
    },
    "python:3.12-slim": {
      "pulled_as": "python:3.12-slim",
      "digest": "python@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1"
    }
  },
  "pull_seconds": 6.3,
  "finished_at": "2026-10-19T03:26:27Z",
  "elapsed_seconds": 794.3,
  "services": {
    "adguardhome": {
      "image_ref": "adguard/adguardhome:v0.107.79",
      "image_repo": "adguard/adguardhome",
      "image_tag": "v0.107.79",
      "digest": "sha256:aba9e3bf0613be3ba3755e1fc311b126e2c24bec25e18b6483894a88283074f0",
      "digest_note": null,
      "version": "v0.107.79",
      "version_source": "label:org.opencontainers.image.version",
      "version_pinned": true,
      "version_note": null,
      "resolved_tag": "v0.107.79",
      "resolved_tag_note": null,
      "image_size": {
        "unpacked_mb": 81.5,
        "unpacked_source": "docker image ls Size: unpacked image on the daemon host, rounded by docker to 3 significant figures",
        "compressed_mb": 29.5,
        "compressed_source": "sum of compressed layer sizes in the registry manifest for linux/amd64",
        "compressed_null_reason": null,
        "unit_note": "MB = 10^6 bytes. unpacked = disk used on the host; compressed = what is downloaded"
      },
      "compose_image": "adguard/adguardhome:v0.107.79",
      "compose_comment": "sha256:aba9e3bf0613be3ba3755e1fc311b126e2c24bec25e18b6483894a88283074f0  (version v0.107.79, from label:org.opencontainers.image.version)",
      "restart_count": 0,
      "oom_killed": false
    }
  },
  "runs": [
    {
      "run": 1,
      "started_at": "2026-10-19T03:13:26Z",
      "host": {
        "label": "github-actions ubuntu-latest (2 vCPU, 8 GB)",
        "ci": {
          "runs_on": "ubuntu-latest",
          "runner_environment": "github-hosted",
          "runner_os": "Linux",
          "runner_arch": "X64",
          "image_os": "ubuntu24",
          "image_version": "20261012.334.1"
        },
        "cpu_model": "AMD EPYC 9V45 96-Core Processor",
        "cpu_model_note": null,
        "cores": 2,
        "mem_total_mib": 7938,
        "kernel": "6.17.0-1022-azure",
        "os": "Ubuntu 24.04.5 LTS",
        "arch": "x86_64",
        "oci_arch": "amd64",
        "docker_server_version": "28.0.4",
        "docker_client_version": "28.0.4",
        "compose_client_version": "2.38.2",
        "storage_driver": "overlay2",
        "containerd_image_store": false,
        "source": "docker info + throwaway container reading /proc/cpuinfo on the daemon host",
        "compose_note": "Compose runs on the client machine; Docker server fields are from the daemon host"
      },
      "date": "2026-10-19",
      "startup": {
        "seconds": 0.4,
        "ok": true,
        "checks": [
          {
            "type": "http",
            "url": "http://adguardhome:3000/control/install/get_addresses",
            "expect_status": [
              200
            ],
            "ok": true,
            "ready_after_s": 0.4,
            "detail": "OK 200"
          }
        ],
        "up_command_seconds": 0.2,
        "definition": "wall clock from starting `docker compose up -d` until every health check passed; checks poll every 0.5 s from a throwaway container on the compose network, so resolution is about +/- 1 s"
      },
      "versions": {
        "adguardhome": "v0.107.79"
      },
      "setup": [
        {
          "exit_code": 0,
          "duration_s": 1.1,
          "reported": {
            "version_reported": "v0.107.79",
            "blocklist": {
              "name": "StevenBlack unified hosts",
              "url": "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
              "entries_reported": 71506,
              "reported_by": "GET /control/filtering/status, filters[].rules_count",
              "filters_removed": [
                "AdGuard DNS filter",
                "AdAway Default Blocklist"
              ]
            },
            "dns_config": {
              "upstream_dns": [
                "1.1.1.1"
              ],
              "upstream_mode": "",
              "ratelimit": 0,
              "blocking_mode": "null_ip",
              "cache_enabled": true,
              "cache_size": 4194304,
              "cache_ttl_min": 0,
              "cache_ttl_max": 0,
              "cache_optimistic": false,
              "dnssec_enabled": false,
              "edns_cs_enabled": false,
              "disable_ipv6": false,
              "protection_enabled": true
            }
          },
          "output_tail": [
            "waiting for the install wizard",
            "wizard done, waiting for the configured server",
            "AdGuard Home v0.107.79 is running, DNS port 53, protection_enabled=True",
            "filter lists removed: AdGuard DNS filter, AdAway Default Blocklist",
            "filter list 'StevenBlack unified hosts': 71506 rules"
          ],
          "description": "Do the first-run wizard through the documented install API (POST /control/install/configure: admin user, web on port 80, DNS on port 53), then set the upstream resolver to plain 1.1.1.1 (a new install uses DNS-over-HTTPS to Quad9), the query rate limit off (default 20 queries/s per client), the DNSSEC flag off and blocking mode null_ip (blocked names answer 0.0.0.0), remove the default filters and add the StevenBlack unified hosts list, the default list of Pi-hole. Reports how many rules AdGuard Home says it loaded."
        }
      ],
      "idle": {
        "per_service": {
          "adguardhome": {
            "samples": 16,
            "mem_mean_mib": 39.25,
            "mem_max_mib": 39.47,
            "cpu_mean_pct": 0.01,
            "cpu_max_pct": 0.01
          }
        },
        "total": {
          "samples": 16,
          "dropped_for_total": 0,
          "mem_mean_mib": 39.25,
          "mem_max_mib": 39.47,
          "cpu_mean_pct": 0.01,
          "cpu_max_pct": 0.01
        },
        "window_seconds": 30.2,
        "series": [
          {
            "t_offset_s": 0.0,
            "total_mem_mib": 39.47,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 2.0,
            "total_mem_mib": 39.47,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 4.0,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 6.0,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 8.1,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 10.1,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 12.1,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 14.1,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 16.1,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 18.1,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 20.1,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 22.2,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 24.2,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 26.2,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 28.2,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 30.2,
            "total_mem_mib": 39.22,
            "total_cpu_pct": 0.01
          }
        ],
        "memory_stat": {
          "read_at": "2026-10-19T03:16:01Z",
          "per_service": {
            "adguardhome": {
              "cgroup": "v2",
              "anon_mib": 38.18,
              "file_mib": 2.0,
              "active_file_mib": 0.0,
              "inactive_file_mib": 2.0,
              "shmem_mib": 0.0
            }
          },
          "read_lag_s": 0.0,
          "method": "docker exec <container> cat /sys/fs/cgroup/memory.stat (cgroup v1: /sys/fs/cgroup/memory/memory.stat); MiB; splits what docker stats shows as one number into anon (heap) and file cache; a field that is absent was not printed by the kernel or not readable (see reason)",
          "taken": "right after the idle window"
        }
      },
      "settle": {
        "settled": true,
        "mode": "detected",
        "settle_seconds_used": 120.9,
        "settle_started_after_healthy_s": 3.6,
        "params": {
          "window_seconds": 60,
          "threshold_pct": 2.0,
          "threshold_min_mib": 10.0,
          "min_seconds": 120,
          "max_seconds": 600
        },
        "last_window": {
          "n": 30,
          "mean_mib": 39.31,
          "min_mib": 39.22,
          "max_mib": 39.47,
          "spread_mib": 0.25,
          "threshold_mib": 10.0
        },
        "rechecks": 0,
        "rule": "settled = over the last window_seconds the stack total varied (max - min) by less than max(threshold_pct of the window mean, threshold_min_mib); not before min_seconds, at the latest max_seconds, both counted from the end of the setup steps; the idle window must also be flat and agree with it. If max_seconds passes without settling, settled=false and the idle window is measured anyway."
      },
      "startup_peak": {
        "per_service_mem_mib": {
          "adguardhome": 41.41
        },
        "total_mem_mib": 41.41,
        "samples": 62,
        "note": "highest value across docker stats samples (about one every 2-3 s) from healthy until the stack settled; shorter spikes between samples are not seen"
      },
      "timeline": {
        "step_s": 10,
        "t0": "healthy",
        "offsets_s": [
          10,
          20,
          30,
          40,
          50,
          60,
          70,
          80,
          90,
          100,
          110,
          120,
          130,
          140,
          150,
          160
        ],
        "total_mem_mib": [
          37.3,
          41.4,
          41.4,
          41.4,
          41.4,
          40.6,
          39.3,
          39.2,
          39.2,
          39.4,
          39.5,
          39.3,
          39.3,
          39.2,
          39.2,
          39.2
        ],
        "per_service_mem_mib": {
          "adguardhome": [
            37.3,
            41.4,
            41.4,
            41.4,
            41.4,
            40.6,
            39.3,
            39.2,
            39.2,
            39.4,
            39.5,
            39.3,
            39.3,
            39.2,
            39.2,
            39.2
          ]
        }
      },
      "load": {
        "per_service": {
          "adguardhome": {
            "samples": 53,
            "mem_mean_mib": 56.12,
            "mem_max_mib": 59.47,
            "cpu_mean_pct": 3.6,
            "cpu_max_pct": 11.14
          }
        },
        "total": {
          "samples": 53,
          "dropped_for_total": 0,
          "mem_mean_mib": 56.12,
          "mem_max_mib": 59.47,
          "cpu_mean_pct": 3.6,
          "cpu_max_pct": 11.14
        },
        "description": "The same script and the same 900 names as the Pi-hole app, against AdGuard Home's port 53 over plain UDP (type A) from a container on the Compose network: 500 real popular domains, 300 names from the StevenBlack blocklist (blocked, answered 0.0.0.0) and 100 random .com names that do not exist (NXDOMAIN). Three phases, queries sent on a fixed schedule whether or not earlier ones were answered: every name once at 100 queries/s (first-time latency, 9 s); 200 queries/s for 60 s, names drawn in shuffled rounds so most are repeats; then a burst of 1,000 queries/s for 20 s. A query not answered within 2 s is a timeout. The script records queries sent, answered, timeouts, blocked answers and the p50, p95 and p99 latency of first-time and of repeated (cache-expected) queries, and reads the resolver's own query counters before and after. No real clients, no DoH/DoT, no DHCP, no reverse lookups.",
        "duration_s": 102.3,
        "window": "from LAB_MARK load_start (or step start) until 2 s after the step ended",
        "reported_by_script": {
          "dns_load": {
            "target": "adguard",
            "resolver": "adguardhome:53",
            "protocol": "udp",
            "query_type": "A",
            "domain_list": {
              "names": 900,
              "allow": 500,
              "block": 300,
              "nx": 100,
              "sha256_16": "459be49b880c5849"
            },
            "preflight": {
              "blocked_probe": "doubleclick.net",
              "allowed_probe": "example.org"
            },
            "seed": 20261013,
            "names_left_out_after_cold_pass": {
              "total": 0,
              "by_category": {},
              "by_class": {}
            },
            "query_timeout_s": 2.0,
            "pause_s": 5,
            "phases": [
              {
                "sent": 900,
                "answered": 900,
                "timeouts": 0,
                "answers_by_class": {
                  "answer": 525,
                  "blocked": 262,
                  "nxdomain": 113
                },
                "blocked_answers": 262,
                "block_names_not_blocked": 38,
                "other_names_blocked": 0,
                "repeats_not_expected_cached": 0,
                "latency_ms": {
                  "first_allow": {
                    "n": 500,
                    "p50": 20.76,
                    "p95": 178.963,
                    "p99": 348.687,
                    "max": 952.756,
                    "mean": 51.647
                  },
                  "first_nx": {
                    "n": 100,
                    "p50": 20.619,
                    "p95": 29.436,
                    "p99": 49.625,
                    "max": 64.776,
                    "mean": 22.047
                  },
                  "cached_allow": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "cached_nx": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "blocked": {
                    "n": 262,
                    "p50": 0.102,
                    "p95": 0.196,
                    "p99": 0.264,
                    "max": 0.332,
                    "mean": 0.106
                  }
                },
                "phase": "cold",
                "target_qps": 100,
                "planned_seconds": 9.0,
                "achieved_qps": 100.0,
                "send_lag_ms": {
                  "p50": 0.091,
                  "p99": 0.263,
                  "max": 0.759
                },
                "names_not_answered": {
                  "total": 0,
                  "by_category": {},
                  "by_class": {}
                }
              },
              {
                "sent": 12000,
                "answered": 12000,
                "timeouts": 0,
                "answers_by_class": {
                  "answer": 6998,
                  "blocked": 3487,
                  "nxdomain": 1515
                },
                "blocked_answers": 3487,
                "block_names_not_blocked": 509,
                "other_names_blocked": 0,
                "repeats_not_expected_cached": 281,
                "latency_ms": {
                  "first_allow": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "first_nx": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "cached_allow": {
                    "n": 6383,
                    "p50": 0.081,
                    "p95": 0.116,
                    "p99": 0.177,
                    "max": 1.46,
                    "mean": 0.078
                  },
                  "cached_nx": {
                    "n": 1340,
                    "p50": 0.08,
                    "p95": 0.115,
                    "p99": 0.19,
                    "max": 0.617,
                    "mean": 0.076
                  },
                  "blocked": {
                    "n": 3487,
                    "p50": 0.076,
                    "p95": 0.108,
                    "p99": 0.157,
                    "max": 0.438,
                    "mean": 0.07
                  }
                },
                "phase": "sustained",
                "target_qps": 200,
                "planned_seconds": 60,
                "achieved_qps": 200.0,
                "send_lag_ms": {
                  "p50": 0.081,
                  "p99": 0.18,
                  "max": 1.051
                }
              },
              {
                "sent": 20000,
                "answered": 20000,
                "timeouts": 0,
                "answers_by_class": {
                  "answer": 11662,
                  "blocked": 5832,
                  "nxdomain": 2506
                },
                "blocked_answers": 5832,
                "block_names_not_blocked": 847,
                "other_names_blocked": 0,
                "repeats_not_expected_cached": 54,
                "latency_ms": {
                  "first_allow": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "first_nx": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "cached_allow": {
                    "n": 11051,
                    "p50": 0.075,
                    "p95": 0.103,
                    "p99": 0.176,
                    "max": 22.635,
                    "mean": 0.077
                  },
                  "cached_nx": {
                    "n": 2216,
                    "p50": 0.075,
                    "p95": 0.099,
                    "p99": 0.152,
                    "max": 2.522,
                    "mean": 0.074
                  },
                  "blocked": {
                    "n": 5832,
                    "p50": 0.071,
                    "p95": 0.095,
                    "p99": 0.14,
                    "max": 1.219,
                    "mean": 0.067
                  }
                },
                "phase": "burst",
                "target_qps": 1000,
                "planned_seconds": 20,
                "achieved_qps": 1000.0,
                "send_lag_ms": {
                  "p50": 0.078,
                  "p99": 0.176,
                  "max": 2.896
                }
              }
            ],
            "overall": {
              "sent": 32900,
              "answered": 32900,
              "timeouts": 0,
              "answers_by_class": {
                "answer": 19185,
                "blocked": 9581,
                "nxdomain": 4134
              },
              "blocked_answers": 9581,
              "block_names_not_blocked": 1394,
              "other_names_blocked": 0,
              "repeats_not_expected_cached": 335,
              "latency_ms": {
                "first_allow": {
                  "n": 500,
                  "p50": 20.76,
                  "p95": 178.963,
                  "p99": 348.687,
                  "max": 952.756,
                  "mean": 51.647
                },
                "first_nx": {
                  "n": 100,
                  "p50": 20.619,
                  "p95": 29.436,
                  "p99": 49.625,
                  "max": 64.776,
                  "mean": 22.047
                },
                "cached_allow": {
                  "n": 17434,
                  "p50": 0.077,
                  "p95": 0.109,
                  "p99": 0.176,
                  "max": 22.635,
                  "mean": 0.077
                },
                "cached_nx": {
                  "n": 3556,
                  "p50": 0.077,
                  "p95": 0.106,
                  "p99": 0.172,
                  "max": 2.522,
                  "mean": 0.075
                },
                "blocked": {
                  "n": 9581,
                  "p50": 0.073,
                  "p95": 0.106,
                  "p99": 0.162,
                  "max": 1.219,
                  "mean": 0.069
                }
              }
            },
            "elapsed_s": 100.1,
            "resolver_counters": {
              "before": {
                "queries_total": 2,
                "queries_blocked": 1,
                "avg_processing_time_s": 0.009741
              },
              "after": {
                "queries_total": 32902,
                "queries_blocked": 9582,
                "avg_processing_time_s": 0.0012209999999999999
              },
              "delta": {
                "queries_total": 32900,
                "queries_blocked": 9581
              }
            },
            "cache_rule": "a repeat counts as cache-expected when an earlier answer for the name arrived less than half its TTL ago"
          },
          "queries_sent": 32900,
          "queries_answered": 32900,
          "timeouts": 0,
          "blocked_answers": 9581,
          "first_allow_p50_ms": 20.76,
          "first_allow_p95_ms": 178.963,
          "first_allow_p99_ms": 348.687,
          "cached_allow_p50_ms": 0.081,
          "cached_allow_p95_ms": 0.116,
          "cached_allow_p99_ms": 0.177,
          "blocked_p50_ms": 0.076,
          "blocked_p95_ms": 0.108,
          "blocked_p99_ms": 0.157,
          "burst_cached_allow_p50_ms": 0.075,
          "burst_cached_allow_p95_ms": 0.103,
          "burst_cached_allow_p99_ms": 0.176
        },
        "output_tail": [
          "resolver adguardhome = 172.18.0.2:53; domain list 900 names {'allow': 500, 'block': 300, 'nx': 100}, sha256 459be49b880c5849",
          "cold: sent 900 answered 900 timeouts 0 blocked 262 achieved 100.0 qps; cached allow p50/p95/p99 None/None/None ms; first allow p50 20.76 ms",
          "sustained: sent 12000 answered 12000 timeouts 0 blocked 3487 achieved 200.0 qps; cached allow p50/p95/p99 0.081/0.116/0.177 ms; first allow p50 None ms",
          "burst: sent 20000 answered 20000 timeouts 0 blocked 5832 achieved 1000.0 qps; cached allow p50/p95/p99 0.075/0.103/0.176 ms; first allow p50 None ms"
        ],
        "series": [
          {
            "t_offset_s": 0.0,
            "total_mem_mib": 39.71,
            "total_cpu_pct": 3.83
          },
          {
            "t_offset_s": 2.0,
            "total_mem_mib": 41.54,
            "total_cpu_pct": 2.11
          },
          {
            "t_offset_s": 4.0,
            "total_mem_mib": 41.64,
            "total_cpu_pct": 2.57
          },
          {
            "t_offset_s": 6.0,
            "total_mem_mib": 43.66,
            "total_cpu_pct": 2.65
          },
          {
            "t_offset_s": 8.0,
            "total_mem_mib": 45.8,
            "total_cpu_pct": 2.76
          },
          {
            "t_offset_s": 10.0,
            "total_mem_mib": 45.72,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 12.0,
            "total_mem_mib": 45.72,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 14.0,
            "total_mem_mib": 45.72,
            "total_cpu_pct": 0.1
          },
          {
            "t_offset_s": 16.0,
            "total_mem_mib": 49.94,
            "total_cpu_pct": 2.05
          },
          {
            "t_offset_s": 18.0,
            "total_mem_mib": 53.99,
            "total_cpu_pct": 2.37
          },
          {
            "t_offset_s": 20.0,
            "total_mem_mib": 56.34,
            "total_cpu_pct": 2.29
          },
          {
            "t_offset_s": 22.0,
            "total_mem_mib": 56.51,
            "total_cpu_pct": 2.1
          },
          {
            "t_offset_s": 24.0,
            "total_mem_mib": 56.63,
            "total_cpu_pct": 2.18
          },
          {
            "t_offset_s": 26.1,
            "total_mem_mib": 56.48,
            "total_cpu_pct": 2.11
          },
          {
            "t_offset_s": 28.1,
            "total_mem_mib": 56.48,
            "total_cpu_pct": 2.48
          },
          {
            "t_offset_s": 30.1,
            "total_mem_mib": 58.45,
            "total_cpu_pct": 2.26
          },
          {
            "t_offset_s": 32.1,
            "total_mem_mib": 58.39,
            "total_cpu_pct": 2.12
          },
          {
            "t_offset_s": 34.1,
            "total_mem_mib": 58.64,
            "total_cpu_pct": 2.54
          },
          {
            "t_offset_s": 36.1,
            "total_mem_mib": 58.5,
            "total_cpu_pct": 2.16
          },
          {
            "t_offset_s": 38.1,
            "total_mem_mib": 58.5,
            "total_cpu_pct": 2.05
          },
          {
            "t_offset_s": 40.1,
            "total_mem_mib": 58.73,
            "total_cpu_pct": 2.43
          },
          {
            "t_offset_s": 42.1,
            "total_mem_mib": 58.92,
            "total_cpu_pct": 2.14
          },
          {
            "t_offset_s": 44.1,
            "total_mem_mib": 58.52,
            "total_cpu_pct": 2.07
          },
          {
            "t_offset_s": 46.1,
            "total_mem_mib": 58.73,
            "total_cpu_pct": 2.07
          },
          {
            "t_offset_s": 48.1,
            "total_mem_mib": 58.73,
            "total_cpu_pct": 2.14
          },
          {
            "t_offset_s": 50.1,
            "total_mem_mib": 58.71,
            "total_cpu_pct": 3.09
          },
          {
            "t_offset_s": 52.1,
            "total_mem_mib": 58.7,
            "total_cpu_pct": 2.04
          },
          {
            "t_offset_s": 54.1,
            "total_mem_mib": 58.9,
            "total_cpu_pct": 2.11
          },
          {
            "t_offset_s": 56.1,
            "total_mem_mib": 58.87,
            "total_cpu_pct": 2.03
          },
          {
            "t_offset_s": 58.1,
            "total_mem_mib": 58.87,
            "total_cpu_pct": 2.08
          },
          {
            "t_offset_s": 60.1,
            "total_mem_mib": 58.84,
            "total_cpu_pct": 3.16
          },
          {
            "t_offset_s": 62.1,
            "total_mem_mib": 58.88,
            "total_cpu_pct": 2.14
          },
          {
            "t_offset_s": 64.1,
            "total_mem_mib": 58.83,
            "total_cpu_pct": 2.19
          },
          {
            "t_offset_s": 66.1,
            "total_mem_mib": 59.04,
            "total_cpu_pct": 2.29
          },
          {
            "t_offset_s": 68.1,
            "total_mem_mib": 58.92,
            "total_cpu_pct": 2.31
          },
          {
            "t_offset_s": 70.1,
            "total_mem_mib": 58.89,
            "total_cpu_pct": 3.45
          },
          {
            "t_offset_s": 72.2,
            "total_mem_mib": 58.88,
            "total_cpu_pct": 2.24
          },
          {
            "t_offset_s": 74.2,
            "total_mem_mib": 58.95,
            "total_cpu_pct": 1.7
          },
          {
            "t_offset_s": 76.2,
            "total_mem_mib": 58.7,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 78.2,
            "total_mem_mib": 58.7,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 80.2,
            "total_mem_mib": 59.13,
            "total_cpu_pct": 11.14
          },
          {
            "t_offset_s": 82.2,
            "total_mem_mib": 59.01,
            "total_cpu_pct": 10.92
          },
          {
            "t_offset_s": 84.2,
            "total_mem_mib": 59.2,
            "total_cpu_pct": 11.08
          },
          {
            "t_offset_s": 86.2,
            "total_mem_mib": 59.26,
            "total_cpu_pct": 10.74
          },
          {
            "t_offset_s": 88.2,
            "total_mem_mib": 59.1,
            "total_cpu_pct": 10.94
          },
          {
            "t_offset_s": 90.2,
            "total_mem_mib": 59.03,
            "total_cpu_pct": 10.9
          },
          {
            "t_offset_s": 92.2,
            "total_mem_mib": 59.21,
            "total_cpu_pct": 10.51
          },
          {
            "t_offset_s": 94.2,
            "total_mem_mib": 59.47,
            "total_cpu_pct": 10.74
          },
          {
            "t_offset_s": 96.2,
            "total_mem_mib": 59.33,
            "total_cpu_pct": 10.68
          },
          {
            "t_offset_s": 98.2,
            "total_mem_mib": 59.26,
            "total_cpu_pct": 10.63
          },
          {
            "t_offset_s": 100.2,
            "total_mem_mib": 59.26,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 102.2,
            "total_mem_mib": 59.09,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 104.2,
            "total_mem_mib": 59.09,
            "total_cpu_pct": 0.01
          }
        ],
        "series_start_offset_s": 1.5,
        "peak_note": "peak = highest value seen across docker stats samples (about one every 2-3 s); shorter spikes between samples are not seen",
        "peak_memory_stat": {
          "read_at": "2026-10-19T03:17:37Z",
          "per_service": {
            "adguardhome": {
              "cgroup": "v2",
              "anon_mib": 57.68,
              "file_mib": 9.96,
              "active_file_mib": 0.0,
              "inactive_file_mib": 9.96,
              "shmem_mib": 0.0
            }
          },
          "read_lag_s": 0.0,
          "series_index": 47,
          "sample_t_offset_s": 94.2,
          "total_mem_mib": 59.47
        }
      },
      "container_end_state": {
        "adguardhome": {
          "restart_count": 0,
          "oom_killed": false
        }
      },
      "teardown": {
        "done": true,
        "volumes_removed": true,
        "images_removed": false,
        "error": null
      },
      "warnings": [],
      "finished_at": "2026-10-19T03:17:47Z",
      "elapsed_seconds": 261.6
    },
    {
      "run": 2,
      "started_at": "2026-10-19T03:17:47Z",
      "host": {
        "label": "github-actions ubuntu-latest (2 vCPU, 8 GB)",
        "ci": {
          "runs_on": "ubuntu-latest",
          "runner_environment": "github-hosted",
          "runner_os": "Linux",
          "runner_arch": "X64",
          "image_os": "ubuntu24",
          "image_version": "20261012.334.1"
        },
        "cpu_model": "AMD EPYC 9V45 96-Core Processor",
        "cpu_model_note": null,
        "cores": 2,
        "mem_total_mib": 7938,
        "kernel": "6.17.0-1022-azure",
        "os": "Ubuntu 24.04.5 LTS",
        "arch": "x86_64",
        "oci_arch": "amd64",
        "docker_server_version": "28.0.4",
        "docker_client_version": "28.0.4",
        "compose_client_version": "2.38.2",
        "storage_driver": "overlay2",
        "containerd_image_store": false,
        "source": "docker info + throwaway container reading /proc/cpuinfo on the daemon host",
        "compose_note": "Compose runs on the client machine; Docker server fields are from the daemon host"
      },
      "date": "2026-10-19",
      "startup": {
        "seconds": 0.4,
        "ok": true,
        "checks": [
          {
            "type": "http",
            "url": "http://adguardhome:3000/control/install/get_addresses",
            "expect_status": [
              200
            ],
            "ok": true,
            "ready_after_s": 0.4,
            "detail": "OK 200"
          }
        ],
        "up_command_seconds": 0.2,
        "definition": "wall clock from starting `docker compose up -d` until every health check passed; checks poll every 0.5 s from a throwaway container on the compose network, so resolution is about +/- 1 s"
      },
      "versions": {
        "adguardhome": "v0.107.79"
      },
      "setup": [
        {
          "exit_code": 0,
          "duration_s": 1.2,
          "reported": {
            "version_reported": "v0.107.79",
            "blocklist": {
              "name": "StevenBlack unified hosts",
              "url": "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
              "entries_reported": 71506,
              "reported_by": "GET /control/filtering/status, filters[].rules_count",
              "filters_removed": [
                "AdGuard DNS filter",
                "AdAway Default Blocklist"
              ]
            },
            "dns_config": {
              "upstream_dns": [
                "1.1.1.1"
              ],
              "upstream_mode": "",
              "ratelimit": 0,
              "blocking_mode": "null_ip",
              "cache_enabled": true,
              "cache_size": 4194304,
              "cache_ttl_min": 0,
              "cache_ttl_max": 0,
              "cache_optimistic": false,
              "dnssec_enabled": false,
              "edns_cs_enabled": false,
              "disable_ipv6": false,
              "protection_enabled": true
            }
          },
          "output_tail": [
            "waiting for the install wizard",
            "wizard done, waiting for the configured server",
            "AdGuard Home v0.107.79 is running, DNS port 53, protection_enabled=True",
            "filter lists removed: AdGuard DNS filter, AdAway Default Blocklist",
            "filter list 'StevenBlack unified hosts': 71506 rules"
          ],
          "description": "Do the first-run wizard through the documented install API (POST /control/install/configure: admin user, web on port 80, DNS on port 53), then set the upstream resolver to plain 1.1.1.1 (a new install uses DNS-over-HTTPS to Quad9), the query rate limit off (default 20 queries/s per client), the DNSSEC flag off and blocking mode null_ip (blocked names answer 0.0.0.0), remove the default filters and add the StevenBlack unified hosts list, the default list of Pi-hole. Reports how many rules AdGuard Home says it loaded."
        }
      ],
      "idle": {
        "per_service": {
          "adguardhome": {
            "samples": 16,
            "mem_mean_mib": 43.27,
            "mem_max_mib": 43.46,
            "cpu_mean_pct": 0.04,
            "cpu_max_pct": 0.48
          }
        },
        "total": {
          "samples": 16,
          "dropped_for_total": 0,
          "mem_mean_mib": 43.27,
          "mem_max_mib": 43.46,
          "cpu_mean_pct": 0.04,
          "cpu_max_pct": 0.48
        },
        "window_seconds": 30.2,
        "series": [
          {
            "t_offset_s": 0.0,
            "total_mem_mib": 43.21,
            "total_cpu_pct": 0.48
          },
          {
            "t_offset_s": 2.0,
            "total_mem_mib": 43.21,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 4.0,
            "total_mem_mib": 43.21,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 6.0,
            "total_mem_mib": 43.21,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 8.1,
            "total_mem_mib": 43.21,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 10.1,
            "total_mem_mib": 43.21,
            "total_cpu_pct": 0.02
          },
          {
            "t_offset_s": 12.1,
            "total_mem_mib": 43.21,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 14.1,
            "total_mem_mib": 43.21,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 16.1,
            "total_mem_mib": 43.21,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 18.1,
            "total_mem_mib": 43.21,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 20.1,
            "total_mem_mib": 43.21,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 22.2,
            "total_mem_mib": 43.21,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 24.2,
            "total_mem_mib": 43.46,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 26.2,
            "total_mem_mib": 43.46,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 28.2,
            "total_mem_mib": 43.46,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 30.2,
            "total_mem_mib": 43.46,
            "total_cpu_pct": 0.01
          }
        ],
        "memory_stat": {
          "read_at": "2026-10-19T03:20:21Z",
          "per_service": {
            "adguardhome": {
              "cgroup": "v2",
              "anon_mib": 42.18,
              "file_mib": 1.99,
              "active_file_mib": 0.0,
              "inactive_file_mib": 1.99,
              "shmem_mib": 0.0
            }
          },
          "read_lag_s": 0.0,
          "method": "docker exec <container> cat /sys/fs/cgroup/memory.stat (cgroup v1: /sys/fs/cgroup/memory/memory.stat); MiB; splits what docker stats shows as one number into anon (heap) and file cache; a field that is absent was not printed by the kernel or not readable (see reason)",
          "taken": "right after the idle window"
        }
      },
      "settle": {
        "settled": true,
        "mode": "detected",
        "settle_seconds_used": 120.9,
        "settle_started_after_healthy_s": 1.5,
        "params": {
          "window_seconds": 60,
          "threshold_pct": 2.0,
          "threshold_min_mib": 10.0,
          "min_seconds": 120,
          "max_seconds": 600
        },
        "last_window": {
          "n": 30,
          "mean_mib": 43.41,
          "min_mib": 43.21,
          "max_mib": 43.71,
          "spread_mib": 0.5,
          "threshold_mib": 10.0
        },
        "rechecks": 0,
        "rule": "settled = over the last window_seconds the stack total varied (max - min) by less than max(threshold_pct of the window mean, threshold_min_mib); not before min_seconds, at the latest max_seconds, both counted from the end of the setup steps; the idle window must also be flat and agree with it. If max_seconds passes without settling, settled=false and the idle window is measured anyway."
      },
      "startup_peak": {
        "per_service_mem_mib": {
          "adguardhome": 45.82
        },
        "total_mem_mib": 45.82,
        "samples": 61,
        "note": "highest value across docker stats samples (about one every 2-3 s) from healthy until the stack settled; shorter spikes between samples are not seen"
      },
      "timeline": {
        "step_s": 10,
        "t0": "healthy",
        "offsets_s": [
          10,
          20,
          30,
          40,
          50,
          60,
          70,
          80,
          90,
          100,
          110,
          120,
          130,
          140,
          150,
          160
        ],
        "total_mem_mib": [
          42.4,
          45.8,
          45.8,
          45.8,
          45.8,
          45.8,
          43.2,
          43.3,
          43.7,
          43.4,
          43.3,
          43.6,
          43.2,
          43.2,
          43.3,
          43.5
        ],
        "per_service_mem_mib": {
          "adguardhome": [
            42.4,
            45.8,
            45.8,
            45.8,
            45.8,
            45.8,
            43.2,
            43.3,
            43.7,
            43.4,
            43.3,
            43.6,
            43.2,
            43.2,
            43.3,
            43.5
          ]
        }
      },
      "load": {
        "per_service": {
          "adguardhome": {
            "samples": 53,
            "mem_mean_mib": 56.68,
            "mem_max_mib": 61.53,
            "cpu_mean_pct": 3.66,
            "cpu_max_pct": 12.81
          }
        },
        "total": {
          "samples": 53,
          "dropped_for_total": 0,
          "mem_mean_mib": 56.68,
          "mem_max_mib": 61.53,
          "cpu_mean_pct": 3.66,
          "cpu_max_pct": 12.81
        },
        "description": "The same script and the same 900 names as the Pi-hole app, against AdGuard Home's port 53 over plain UDP (type A) from a container on the Compose network: 500 real popular domains, 300 names from the StevenBlack blocklist (blocked, answered 0.0.0.0) and 100 random .com names that do not exist (NXDOMAIN). Three phases, queries sent on a fixed schedule whether or not earlier ones were answered: every name once at 100 queries/s (first-time latency, 9 s); 200 queries/s for 60 s, names drawn in shuffled rounds so most are repeats; then a burst of 1,000 queries/s for 20 s. A query not answered within 2 s is a timeout. The script records queries sent, answered, timeouts, blocked answers and the p50, p95 and p99 latency of first-time and of repeated (cache-expected) queries, and reads the resolver's own query counters before and after. No real clients, no DoH/DoT, no DHCP, no reverse lookups.",
        "duration_s": 102.4,
        "window": "from LAB_MARK load_start (or step start) until 2 s after the step ended",
        "reported_by_script": {
          "dns_load": {
            "target": "adguard",
            "resolver": "adguardhome:53",
            "protocol": "udp",
            "query_type": "A",
            "domain_list": {
              "names": 900,
              "allow": 500,
              "block": 300,
              "nx": 100,
              "sha256_16": "459be49b880c5849"
            },
            "preflight": {
              "blocked_probe": "doubleclick.net",
              "allowed_probe": "example.org"
            },
            "seed": 20261013,
            "names_left_out_after_cold_pass": {
              "total": 0,
              "by_category": {},
              "by_class": {}
            },
            "query_timeout_s": 2.0,
            "pause_s": 5,
            "phases": [
              {
                "sent": 900,
                "answered": 900,
                "timeouts": 0,
                "answers_by_class": {
                  "answer": 525,
                  "blocked": 262,
                  "nxdomain": 113
                },
                "blocked_answers": 262,
                "block_names_not_blocked": 38,
                "other_names_blocked": 0,
                "repeats_not_expected_cached": 0,
                "latency_ms": {
                  "first_allow": {
                    "n": 500,
                    "p50": 20.668,
                    "p95": 185.266,
                    "p99": 285.418,
                    "max": 1034.962,
                    "mean": 51.78
                  },
                  "first_nx": {
                    "n": 100,
                    "p50": 20.075,
                    "p95": 30.029,
                    "p99": 44.192,
                    "max": 66.342,
                    "mean": 21.654
                  },
                  "cached_allow": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "cached_nx": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "blocked": {
                    "n": 262,
                    "p50": 0.093,
                    "p95": 0.124,
                    "p99": 0.165,
                    "max": 0.396,
                    "mean": 0.088
                  }
                },
                "phase": "cold",
                "target_qps": 100,
                "planned_seconds": 9.0,
                "achieved_qps": 100.0,
                "send_lag_ms": {
                  "p50": 0.087,
                  "p99": 0.204,
                  "max": 0.525
                },
                "names_not_answered": {
                  "total": 0,
                  "by_category": {},
                  "by_class": {}
                }
              },
              {
                "sent": 12000,
                "answered": 12000,
                "timeouts": 0,
                "answers_by_class": {
                  "answer": 6998,
                  "blocked": 3487,
                  "nxdomain": 1515
                },
                "blocked_answers": 3487,
                "block_names_not_blocked": 509,
                "other_names_blocked": 0,
                "repeats_not_expected_cached": 275,
                "latency_ms": {
                  "first_allow": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "first_nx": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "cached_allow": {
                    "n": 6389,
                    "p50": 0.081,
                    "p95": 0.116,
                    "p99": 0.172,
                    "max": 1.182,
                    "mean": 0.077
                  },
                  "cached_nx": {
                    "n": 1340,
                    "p50": 0.08,
                    "p95": 0.115,
                    "p99": 0.164,
                    "max": 0.452,
                    "mean": 0.076
                  },
                  "blocked": {
                    "n": 3487,
                    "p50": 0.077,
                    "p95": 0.108,
                    "p99": 0.166,
                    "max": 0.421,
                    "mean": 0.072
                  }
                },
                "phase": "sustained",
                "target_qps": 200,
                "planned_seconds": 60,
                "achieved_qps": 200.0,
                "send_lag_ms": {
                  "p50": 0.082,
                  "p99": 0.182,
                  "max": 1.937
                }
              },
              {
                "sent": 20000,
                "answered": 20000,
                "timeouts": 0,
                "answers_by_class": {
                  "answer": 11662,
                  "blocked": 5832,
                  "nxdomain": 2506
                },
                "blocked_answers": 5832,
                "block_names_not_blocked": 847,
                "other_names_blocked": 0,
                "repeats_not_expected_cached": 43,
                "latency_ms": {
                  "first_allow": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "first_nx": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "cached_allow": {
                    "n": 11062,
                    "p50": 0.077,
                    "p95": 0.105,
                    "p99": 0.187,
                    "max": 15.88,
                    "mean": 0.076
                  },
                  "cached_nx": {
                    "n": 2216,
                    "p50": 0.076,
                    "p95": 0.103,
                    "p99": 0.164,
                    "max": 2.334,
                    "mean": 0.074
                  },
                  "blocked": {
                    "n": 5832,
                    "p50": 0.072,
                    "p95": 0.098,
                    "p99": 0.137,
                    "max": 4.612,
                    "mean": 0.069
                  }
                },
                "phase": "burst",
                "target_qps": 1000,
                "planned_seconds": 20,
                "achieved_qps": 1000.0,
                "send_lag_ms": {
                  "p50": 0.079,
                  "p99": 0.175,
                  "max": 0.914
                }
              }
            ],
            "overall": {
              "sent": 32900,
              "answered": 32900,
              "timeouts": 0,
              "answers_by_class": {
                "answer": 19185,
                "blocked": 9581,
                "nxdomain": 4134
              },
              "blocked_answers": 9581,
              "block_names_not_blocked": 1394,
              "other_names_blocked": 0,
              "repeats_not_expected_cached": 318,
              "latency_ms": {
                "first_allow": {
                  "n": 500,
                  "p50": 20.668,
                  "p95": 185.266,
                  "p99": 285.418,
                  "max": 1034.962,
                  "mean": 51.78
                },
                "first_nx": {
                  "n": 100,
                  "p50": 20.075,
                  "p95": 30.029,
                  "p99": 44.192,
                  "max": 66.342,
                  "mean": 21.654
                },
                "cached_allow": {
                  "n": 17451,
                  "p50": 0.078,
                  "p95": 0.11,
                  "p99": 0.177,
                  "max": 15.88,
                  "mean": 0.076
                },
                "cached_nx": {
                  "n": 3556,
                  "p50": 0.077,
                  "p95": 0.109,
                  "p99": 0.164,
                  "max": 2.334,
                  "mean": 0.075
                },
                "blocked": {
                  "n": 9581,
                  "p50": 0.074,
                  "p95": 0.104,
                  "p99": 0.149,
                  "max": 4.612,
                  "mean": 0.071
                }
              }
            },
            "elapsed_s": 100.1,
            "resolver_counters": {
              "before": {
                "queries_total": 2,
                "queries_blocked": 1,
                "avg_processing_time_s": 0.009844
              },
              "after": {
                "queries_total": 32902,
                "queries_blocked": 9582,
                "avg_processing_time_s": 0.001298
              },
              "delta": {
                "queries_total": 32900,
                "queries_blocked": 9581
              }
            },
            "cache_rule": "a repeat counts as cache-expected when an earlier answer for the name arrived less than half its TTL ago"
          },
          "queries_sent": 32900,
          "queries_answered": 32900,
          "timeouts": 0,
          "blocked_answers": 9581,
          "first_allow_p50_ms": 20.668,
          "first_allow_p95_ms": 185.266,
          "first_allow_p99_ms": 285.418,
          "cached_allow_p50_ms": 0.081,
          "cached_allow_p95_ms": 0.116,
          "cached_allow_p99_ms": 0.172,
          "blocked_p50_ms": 0.077,
          "blocked_p95_ms": 0.108,
          "blocked_p99_ms": 0.166,
          "burst_cached_allow_p50_ms": 0.077,
          "burst_cached_allow_p95_ms": 0.105,
          "burst_cached_allow_p99_ms": 0.187
        },
        "output_tail": [
          "resolver adguardhome = 172.18.0.2:53; domain list 900 names {'allow': 500, 'block': 300, 'nx': 100}, sha256 459be49b880c5849",
          "cold: sent 900 answered 900 timeouts 0 blocked 262 achieved 100.0 qps; cached allow p50/p95/p99 None/None/None ms; first allow p50 20.668 ms",
          "sustained: sent 12000 answered 12000 timeouts 0 blocked 3487 achieved 200.0 qps; cached allow p50/p95/p99 0.081/0.116/0.172 ms; first allow p50 None ms",
          "burst: sent 20000 answered 20000 timeouts 0 blocked 5832 achieved 1000.0 qps; cached allow p50/p95/p99 0.077/0.105/0.187 ms; first allow p50 None ms"
        ],
        "series": [
          {
            "t_offset_s": 0.0,
            "total_mem_mib": 43.75,
            "total_cpu_pct": 1.93
          },
          {
            "t_offset_s": 2.0,
            "total_mem_mib": 43.88,
            "total_cpu_pct": 1.94
          },
          {
            "t_offset_s": 4.0,
            "total_mem_mib": 43.62,
            "total_cpu_pct": 2.01
          },
          {
            "t_offset_s": 6.0,
            "total_mem_mib": 43.87,
            "total_cpu_pct": 2.06
          },
          {
            "t_offset_s": 8.0,
            "total_mem_mib": 45.87,
            "total_cpu_pct": 1.95
          },
          {
            "t_offset_s": 10.0,
            "total_mem_mib": 45.77,
            "total_cpu_pct": 0.02
          },
          {
            "t_offset_s": 12.0,
            "total_mem_mib": 45.77,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 14.0,
            "total_mem_mib": 45.72,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 16.0,
            "total_mem_mib": 49.89,
            "total_cpu_pct": 2.12
          },
          {
            "t_offset_s": 18.0,
            "total_mem_mib": 53.98,
            "total_cpu_pct": 2.22
          },
          {
            "t_offset_s": 20.0,
            "total_mem_mib": 56.4,
            "total_cpu_pct": 3.14
          },
          {
            "t_offset_s": 22.0,
            "total_mem_mib": 56.54,
            "total_cpu_pct": 2.03
          },
          {
            "t_offset_s": 24.1,
            "total_mem_mib": 56.44,
            "total_cpu_pct": 2.09
          },
          {
            "t_offset_s": 26.1,
            "total_mem_mib": 58.66,
            "total_cpu_pct": 2.11
          },
          {
            "t_offset_s": 28.1,
            "total_mem_mib": 58.36,
            "total_cpu_pct": 2.07
          },
          {
            "t_offset_s": 30.1,
            "total_mem_mib": 58.58,
            "total_cpu_pct": 3.12
          },
          {
            "t_offset_s": 32.1,
            "total_mem_mib": 58.55,
            "total_cpu_pct": 2.07
          },
          {
            "t_offset_s": 34.1,
            "total_mem_mib": 58.68,
            "total_cpu_pct": 2.04
          },
          {
            "t_offset_s": 36.1,
            "total_mem_mib": 58.81,
            "total_cpu_pct": 2.22
          },
          {
            "t_offset_s": 38.1,
            "total_mem_mib": 58.71,
            "total_cpu_pct": 2.05
          },
          {
            "t_offset_s": 40.1,
            "total_mem_mib": 58.93,
            "total_cpu_pct": 3.16
          },
          {
            "t_offset_s": 42.1,
            "total_mem_mib": 58.84,
            "total_cpu_pct": 2.09
          },
          {
            "t_offset_s": 44.1,
            "total_mem_mib": 58.85,
            "total_cpu_pct": 2.16
          },
          {
            "t_offset_s": 46.1,
            "total_mem_mib": 58.81,
            "total_cpu_pct": 2.15
          },
          {
            "t_offset_s": 48.1,
            "total_mem_mib": 58.85,
            "total_cpu_pct": 2.17
          },
          {
            "t_offset_s": 50.1,
            "total_mem_mib": 59.07,
            "total_cpu_pct": 2.21
          },
          {
            "t_offset_s": 52.1,
            "total_mem_mib": 58.68,
            "total_cpu_pct": 2.16
          },
          {
            "t_offset_s": 54.1,
            "total_mem_mib": 58.92,
            "total_cpu_pct": 2.11
          },
          {
            "t_offset_s": 56.1,
            "total_mem_mib": 59.14,
            "total_cpu_pct": 2.14
          },
          {
            "t_offset_s": 58.1,
            "total_mem_mib": 59.0,
            "total_cpu_pct": 2.11
          },
          {
            "t_offset_s": 60.1,
            "total_mem_mib": 59.21,
            "total_cpu_pct": 2.33
          },
          {
            "t_offset_s": 62.1,
            "total_mem_mib": 58.89,
            "total_cpu_pct": 2.41
          },
          {
            "t_offset_s": 64.1,
            "total_mem_mib": 59.07,
            "total_cpu_pct": 2.26
          },
          {
            "t_offset_s": 66.1,
            "total_mem_mib": 59.04,
            "total_cpu_pct": 2.46
          },
          {
            "t_offset_s": 68.1,
            "total_mem_mib": 59.03,
            "total_cpu_pct": 2.35
          },
          {
            "t_offset_s": 70.1,
            "total_mem_mib": 59.25,
            "total_cpu_pct": 2.32
          },
          {
            "t_offset_s": 72.2,
            "total_mem_mib": 59.16,
            "total_cpu_pct": 2.35
          },
          {
            "t_offset_s": 74.2,
            "total_mem_mib": 58.99,
            "total_cpu_pct": 1.94
          },
          {
            "t_offset_s": 76.2,
            "total_mem_mib": 58.99,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 78.2,
            "total_mem_mib": 58.78,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 80.2,
            "total_mem_mib": 59.25,
            "total_cpu_pct": 11.32
          },
          {
            "t_offset_s": 82.2,
            "total_mem_mib": 59.18,
            "total_cpu_pct": 11.07
          },
          {
            "t_offset_s": 84.2,
            "total_mem_mib": 59.32,
            "total_cpu_pct": 11.27
          },
          {
            "t_offset_s": 86.2,
            "total_mem_mib": 59.18,
            "total_cpu_pct": 11.04
          },
          {
            "t_offset_s": 88.2,
            "total_mem_mib": 59.36,
            "total_cpu_pct": 10.92
          },
          {
            "t_offset_s": 90.2,
            "total_mem_mib": 59.21,
            "total_cpu_pct": 10.99
          },
          {
            "t_offset_s": 92.2,
            "total_mem_mib": 59.45,
            "total_cpu_pct": 12.81
          },
          {
            "t_offset_s": 94.2,
            "total_mem_mib": 61.47,
            "total_cpu_pct": 12.31
          },
          {
            "t_offset_s": 96.2,
            "total_mem_mib": 61.17,
            "total_cpu_pct": 12.01
          },
          {
            "t_offset_s": 98.2,
            "total_mem_mib": 61.53,
            "total_cpu_pct": 11.98
          },
          {
            "t_offset_s": 100.2,
            "total_mem_mib": 61.41,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 102.2,
            "total_mem_mib": 61.1,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 104.2,
            "total_mem_mib": 61.1,
            "total_cpu_pct": 0.01
          }
        ],
        "series_start_offset_s": 1.5,
        "peak_note": "peak = highest value seen across docker stats samples (about one every 2-3 s); shorter spikes between samples are not seen",
        "peak_memory_stat": {
          "read_at": "2026-10-19T03:22:01Z",
          "per_service": {
            "adguardhome": {
              "cgroup": "v2",
              "anon_mib": 59.73,
              "file_mib": 11.09,
              "active_file_mib": 0.0,
              "inactive_file_mib": 11.09,
              "shmem_mib": 0.0
            }
          },
          "read_lag_s": 0.0,
          "series_index": 49,
          "sample_t_offset_s": 98.2,
          "total_mem_mib": 61.53
        }
      },
      "container_end_state": {
        "adguardhome": {
          "restart_count": 0,
          "oom_killed": false
        }
      },
      "teardown": {
        "done": true,
        "volumes_removed": true,
        "images_removed": false,
        "error": null
      },
      "warnings": [],
      "finished_at": "2026-10-19T03:22:07Z",
      "elapsed_seconds": 259.9
    },
    {
      "run": 3,
      "started_at": "2026-10-19T03:22:07Z",
      "host": {
        "label": "github-actions ubuntu-latest (2 vCPU, 8 GB)",
        "ci": {
          "runs_on": "ubuntu-latest",
          "runner_environment": "github-hosted",
          "runner_os": "Linux",
          "runner_arch": "X64",
          "image_os": "ubuntu24",
          "image_version": "20261012.334.1"
        },
        "cpu_model": "AMD EPYC 9V45 96-Core Processor",
        "cpu_model_note": null,
        "cores": 2,
        "mem_total_mib": 7938,
        "kernel": "6.17.0-1022-azure",
        "os": "Ubuntu 24.04.5 LTS",
        "arch": "x86_64",
        "oci_arch": "amd64",
        "docker_server_version": "28.0.4",
        "docker_client_version": "28.0.4",
        "compose_client_version": "2.38.2",
        "storage_driver": "overlay2",
        "containerd_image_store": false,
        "source": "docker info + throwaway container reading /proc/cpuinfo on the daemon host",
        "compose_note": "Compose runs on the client machine; Docker server fields are from the daemon host"
      },
      "date": "2026-10-19",
      "startup": {
        "seconds": 0.4,
        "ok": true,
        "checks": [
          {
            "type": "http",
            "url": "http://adguardhome:3000/control/install/get_addresses",
            "expect_status": [
              200
            ],
            "ok": true,
            "ready_after_s": 0.4,
            "detail": "OK 200"
          }
        ],
        "up_command_seconds": 0.2,
        "definition": "wall clock from starting `docker compose up -d` until every health check passed; checks poll every 0.5 s from a throwaway container on the compose network, so resolution is about +/- 1 s"
      },
      "versions": {
        "adguardhome": "v0.107.79"
      },
      "setup": [
        {
          "exit_code": 0,
          "duration_s": 1.2,
          "reported": {
            "version_reported": "v0.107.79",
            "blocklist": {
              "name": "StevenBlack unified hosts",
              "url": "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
              "entries_reported": 71506,
              "reported_by": "GET /control/filtering/status, filters[].rules_count",
              "filters_removed": [
                "AdGuard DNS filter",
                "AdAway Default Blocklist"
              ]
            },
            "dns_config": {
              "upstream_dns": [
                "1.1.1.1"
              ],
              "upstream_mode": "",
              "ratelimit": 0,
              "blocking_mode": "null_ip",
              "cache_enabled": true,
              "cache_size": 4194304,
              "cache_ttl_min": 0,
              "cache_ttl_max": 0,
              "cache_optimistic": false,
              "dnssec_enabled": false,
              "edns_cs_enabled": false,
              "disable_ipv6": false,
              "protection_enabled": true
            }
          },
          "output_tail": [
            "waiting for the install wizard",
            "wizard done, waiting for the configured server",
            "AdGuard Home v0.107.79 is running, DNS port 53, protection_enabled=True",
            "filter lists removed: AdGuard DNS filter, AdAway Default Blocklist",
            "filter list 'StevenBlack unified hosts': 71506 rules"
          ],
          "description": "Do the first-run wizard through the documented install API (POST /control/install/configure: admin user, web on port 80, DNS on port 53), then set the upstream resolver to plain 1.1.1.1 (a new install uses DNS-over-HTTPS to Quad9), the query rate limit off (default 20 queries/s per client), the DNSSEC flag off and blocking mode null_ip (blocked names answer 0.0.0.0), remove the default filters and add the StevenBlack unified hosts list, the default list of Pi-hole. Reports how many rules AdGuard Home says it loaded."
        }
      ],
      "idle": {
        "per_service": {
          "adguardhome": {
            "samples": 16,
            "mem_mean_mib": 39.23,
            "mem_max_mib": 39.23,
            "cpu_mean_pct": 0.04,
            "cpu_max_pct": 0.51
          }
        },
        "total": {
          "samples": 16,
          "dropped_for_total": 0,
          "mem_mean_mib": 39.23,
          "mem_max_mib": 39.23,
          "cpu_mean_pct": 0.04,
          "cpu_max_pct": 0.51
        },
        "window_seconds": 30.2,
        "series": [
          {
            "t_offset_s": 0.0,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.51
          },
          {
            "t_offset_s": 2.0,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 4.0,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 6.0,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 8.1,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 10.1,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 12.1,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 14.1,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 16.1,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 18.1,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 20.1,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 22.2,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 24.2,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.03
          },
          {
            "t_offset_s": 26.2,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 28.2,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.02
          },
          {
            "t_offset_s": 30.2,
            "total_mem_mib": 39.23,
            "total_cpu_pct": 0.01
          }
        ],
        "memory_stat": {
          "read_at": "2026-10-19T03:24:41Z",
          "per_service": {
            "adguardhome": {
              "cgroup": "v2",
              "anon_mib": 38.18,
              "file_mib": 1.99,
              "active_file_mib": 0.0,
              "inactive_file_mib": 1.99,
              "shmem_mib": 0.0
            }
          },
          "read_lag_s": 0.0,
          "method": "docker exec <container> cat /sys/fs/cgroup/memory.stat (cgroup v1: /sys/fs/cgroup/memory/memory.stat); MiB; splits what docker stats shows as one number into anon (heap) and file cache; a field that is absent was not printed by the kernel or not readable (see reason)",
          "taken": "right after the idle window"
        }
      },
      "settle": {
        "settled": true,
        "mode": "detected",
        "settle_seconds_used": 120.9,
        "settle_started_after_healthy_s": 1.5,
        "params": {
          "window_seconds": 60,
          "threshold_pct": 2.0,
          "threshold_min_mib": 10.0,
          "min_seconds": 120,
          "max_seconds": 600
        },
        "last_window": {
          "n": 30,
          "mean_mib": 39.67,
          "min_mib": 39.23,
          "max_mib": 41.48,
          "spread_mib": 2.25,
          "threshold_mib": 10.0
        },
        "rechecks": 0,
        "rule": "settled = over the last window_seconds the stack total varied (max - min) by less than max(threshold_pct of the window mean, threshold_min_mib); not before min_seconds, at the latest max_seconds, both counted from the end of the setup steps; the idle window must also be flat and agree with it. If max_seconds passes without settling, settled=false and the idle window is measured anyway."
      },
      "startup_peak": {
        "per_service_mem_mib": {
          "adguardhome": 41.8
        },
        "total_mem_mib": 41.8,
        "samples": 61,
        "note": "highest value across docker stats samples (about one every 2-3 s) from healthy until the stack settled; shorter spikes between samples are not seen"
      },
      "timeline": {
        "step_s": 10,
        "t0": "healthy",
        "offsets_s": [
          10,
          20,
          30,
          40,
          50,
          60,
          70,
          80,
          90,
          100,
          110,
          120,
          130,
          140,
          150,
          160
        ],
        "total_mem_mib": [
          41.4,
          41.2,
          41.3,
          41.2,
          41.4,
          41.4,
          41.1,
          40.0,
          39.5,
          39.4,
          39.4,
          39.4,
          39.2,
          39.2,
          39.2,
          39.2
        ],
        "per_service_mem_mib": {
          "adguardhome": [
            41.4,
            41.2,
            41.3,
            41.2,
            41.4,
            41.4,
            41.1,
            40.0,
            39.5,
            39.4,
            39.4,
            39.4,
            39.2,
            39.2,
            39.2,
            39.2
          ]
        }
      },
      "load": {
        "per_service": {
          "adguardhome": {
            "samples": 53,
            "mem_mean_mib": 57.03,
            "mem_max_mib": 61.37,
            "cpu_mean_pct": 3.61,
            "cpu_max_pct": 11.71
          }
        },
        "total": {
          "samples": 53,
          "dropped_for_total": 0,
          "mem_mean_mib": 57.03,
          "mem_max_mib": 61.37,
          "cpu_mean_pct": 3.61,
          "cpu_max_pct": 11.71
        },
        "description": "The same script and the same 900 names as the Pi-hole app, against AdGuard Home's port 53 over plain UDP (type A) from a container on the Compose network: 500 real popular domains, 300 names from the StevenBlack blocklist (blocked, answered 0.0.0.0) and 100 random .com names that do not exist (NXDOMAIN). Three phases, queries sent on a fixed schedule whether or not earlier ones were answered: every name once at 100 queries/s (first-time latency, 9 s); 200 queries/s for 60 s, names drawn in shuffled rounds so most are repeats; then a burst of 1,000 queries/s for 20 s. A query not answered within 2 s is a timeout. The script records queries sent, answered, timeouts, blocked answers and the p50, p95 and p99 latency of first-time and of repeated (cache-expected) queries, and reads the resolver's own query counters before and after. No real clients, no DoH/DoT, no DHCP, no reverse lookups.",
        "duration_s": 102.3,
        "window": "from LAB_MARK load_start (or step start) until 2 s after the step ended",
        "reported_by_script": {
          "dns_load": {
            "target": "adguard",
            "resolver": "adguardhome:53",
            "protocol": "udp",
            "query_type": "A",
            "domain_list": {
              "names": 900,
              "allow": 500,
              "block": 300,
              "nx": 100,
              "sha256_16": "459be49b880c5849"
            },
            "preflight": {
              "blocked_probe": "doubleclick.net",
              "allowed_probe": "example.org"
            },
            "seed": 20261013,
            "names_left_out_after_cold_pass": {
              "total": 0,
              "by_category": {},
              "by_class": {}
            },
            "query_timeout_s": 2.0,
            "pause_s": 5,
            "phases": [
              {
                "sent": 900,
                "answered": 900,
                "timeouts": 0,
                "answers_by_class": {
                  "answer": 525,
                  "blocked": 262,
                  "nxdomain": 113
                },
                "blocked_answers": 262,
                "block_names_not_blocked": 38,
                "other_names_blocked": 0,
                "repeats_not_expected_cached": 0,
                "latency_ms": {
                  "first_allow": {
                    "n": 500,
                    "p50": 20.476,
                    "p95": 178.768,
                    "p99": 282.894,
                    "max": 958.882,
                    "mean": 51.549
                  },
                  "first_nx": {
                    "n": 100,
                    "p50": 20.396,
                    "p95": 29.949,
                    "p99": 58.414,
                    "max": 70.789,
                    "mean": 22.678
                  },
                  "cached_allow": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "cached_nx": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "blocked": {
                    "n": 262,
                    "p50": 0.096,
                    "p95": 0.147,
                    "p99": 0.252,
                    "max": 0.739,
                    "mean": 0.097
                  }
                },
                "phase": "cold",
                "target_qps": 100,
                "planned_seconds": 9.0,
                "achieved_qps": 100.0,
                "send_lag_ms": {
                  "p50": 0.087,
                  "p99": 0.235,
                  "max": 0.646
                },
                "names_not_answered": {
                  "total": 0,
                  "by_category": {},
                  "by_class": {}
                }
              },
              {
                "sent": 12000,
                "answered": 12000,
                "timeouts": 0,
                "answers_by_class": {
                  "answer": 6998,
                  "blocked": 3487,
                  "nxdomain": 1515
                },
                "blocked_answers": 3487,
                "block_names_not_blocked": 509,
                "other_names_blocked": 0,
                "repeats_not_expected_cached": 288,
                "latency_ms": {
                  "first_allow": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "first_nx": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "cached_allow": {
                    "n": 6376,
                    "p50": 0.08,
                    "p95": 0.116,
                    "p99": 0.177,
                    "max": 0.7,
                    "mean": 0.076
                  },
                  "cached_nx": {
                    "n": 1340,
                    "p50": 0.08,
                    "p95": 0.113,
                    "p99": 0.158,
                    "max": 0.663,
                    "mean": 0.076
                  },
                  "blocked": {
                    "n": 3487,
                    "p50": 0.075,
                    "p95": 0.109,
                    "p99": 0.187,
                    "max": 1.582,
                    "mean": 0.072
                  }
                },
                "phase": "sustained",
                "target_qps": 200,
                "planned_seconds": 60,
                "achieved_qps": 200.0,
                "send_lag_ms": {
                  "p50": 0.082,
                  "p99": 0.202,
                  "max": 0.819
                }
              },
              {
                "sent": 20000,
                "answered": 20000,
                "timeouts": 0,
                "answers_by_class": {
                  "answer": 11662,
                  "blocked": 5832,
                  "nxdomain": 2506
                },
                "blocked_answers": 5832,
                "block_names_not_blocked": 847,
                "other_names_blocked": 0,
                "repeats_not_expected_cached": 48,
                "latency_ms": {
                  "first_allow": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "first_nx": {
                    "n": 0,
                    "p50": null,
                    "p95": null,
                    "p99": null,
                    "max": null,
                    "mean": null
                  },
                  "cached_allow": {
                    "n": 11057,
                    "p50": 0.075,
                    "p95": 0.1,
                    "p99": 0.149,
                    "max": 675.198,
                    "mean": 0.136
                  },
                  "cached_nx": {
                    "n": 2216,
                    "p50": 0.075,
                    "p95": 0.1,
                    "p99": 0.168,
                    "max": 2.23,
                    "mean": 0.072
                  },
                  "blocked": {
                    "n": 5832,
                    "p50": 0.071,
                    "p95": 0.094,
                    "p99": 0.136,
                    "max": 1.195,
                    "mean": 0.067
                  }
                },
                "phase": "burst",
                "target_qps": 1000,
                "planned_seconds": 20,
                "achieved_qps": 1000.0,
                "send_lag_ms": {
                  "p50": 0.078,
                  "p99": 0.158,
                  "max": 1.201
                }
              }
            ],
            "overall": {
              "sent": 32900,
              "answered": 32900,
              "timeouts": 0,
              "answers_by_class": {
                "answer": 19185,
                "blocked": 9581,
                "nxdomain": 4134
              },
              "blocked_answers": 9581,
              "block_names_not_blocked": 1394,
              "other_names_blocked": 0,
              "repeats_not_expected_cached": 336,
              "latency_ms": {
                "first_allow": {
                  "n": 500,
                  "p50": 20.476,
                  "p95": 178.768,
                  "p99": 282.894,
                  "max": 958.882,
                  "mean": 51.549
                },
                "first_nx": {
                  "n": 100,
                  "p50": 20.396,
                  "p95": 29.949,
                  "p99": 58.414,
                  "max": 70.789,
                  "mean": 22.678
                },
                "cached_allow": {
                  "n": 17433,
                  "p50": 0.077,
                  "p95": 0.107,
                  "p99": 0.162,
                  "max": 675.198,
                  "mean": 0.114
                },
                "cached_nx": {
                  "n": 3556,
                  "p50": 0.076,
                  "p95": 0.106,
                  "p99": 0.164,
                  "max": 2.23,
                  "mean": 0.074
                },
                "blocked": {
                  "n": 9581,
                  "p50": 0.073,
                  "p95": 0.104,
                  "p99": 0.164,
                  "max": 1.582,
                  "mean": 0.069
                }
              }
            },
            "elapsed_s": 100.1,
            "resolver_counters": {
              "before": {
                "queries_total": 2,
                "queries_blocked": 1,
                "avg_processing_time_s": 0.009411
              },
              "after": {
                "queries_total": 32902,
                "queries_blocked": 9582,
                "avg_processing_time_s": 0.001287
              },
              "delta": {
                "queries_total": 32900,
                "queries_blocked": 9581
              }
            },
            "cache_rule": "a repeat counts as cache-expected when an earlier answer for the name arrived less than half its TTL ago"
          },
          "queries_sent": 32900,
          "queries_answered": 32900,
          "timeouts": 0,
          "blocked_answers": 9581,
          "first_allow_p50_ms": 20.476,
          "first_allow_p95_ms": 178.768,
          "first_allow_p99_ms": 282.894,
          "cached_allow_p50_ms": 0.08,
          "cached_allow_p95_ms": 0.116,
          "cached_allow_p99_ms": 0.177,
          "blocked_p50_ms": 0.075,
          "blocked_p95_ms": 0.109,
          "blocked_p99_ms": 0.187,
          "burst_cached_allow_p50_ms": 0.075,
          "burst_cached_allow_p95_ms": 0.1,
          "burst_cached_allow_p99_ms": 0.149
        },
        "output_tail": [
          "resolver adguardhome = 172.18.0.2:53; domain list 900 names {'allow': 500, 'block': 300, 'nx': 100}, sha256 459be49b880c5849",
          "cold: sent 900 answered 900 timeouts 0 blocked 262 achieved 100.0 qps; cached allow p50/p95/p99 None/None/None ms; first allow p50 20.476 ms",
          "sustained: sent 12000 answered 12000 timeouts 0 blocked 3487 achieved 200.0 qps; cached allow p50/p95/p99 0.08/0.116/0.177 ms; first allow p50 None ms",
          "burst: sent 20000 answered 20000 timeouts 0 blocked 5832 achieved 1000.0 qps; cached allow p50/p95/p99 0.075/0.1/0.149 ms; first allow p50 None ms"
        ],
        "series": [
          {
            "t_offset_s": 0.0,
            "total_mem_mib": 39.74,
            "total_cpu_pct": 6.38
          },
          {
            "t_offset_s": 2.0,
            "total_mem_mib": 41.38,
            "total_cpu_pct": 1.92
          },
          {
            "t_offset_s": 4.0,
            "total_mem_mib": 41.76,
            "total_cpu_pct": 1.9
          },
          {
            "t_offset_s": 6.0,
            "total_mem_mib": 43.73,
            "total_cpu_pct": 1.97
          },
          {
            "t_offset_s": 8.0,
            "total_mem_mib": 45.87,
            "total_cpu_pct": 2.14
          },
          {
            "t_offset_s": 10.0,
            "total_mem_mib": 45.78,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 12.0,
            "total_mem_mib": 45.78,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 14.0,
            "total_mem_mib": 45.67,
            "total_cpu_pct": 0.02
          },
          {
            "t_offset_s": 16.0,
            "total_mem_mib": 49.89,
            "total_cpu_pct": 2.32
          },
          {
            "t_offset_s": 18.0,
            "total_mem_mib": 54.13,
            "total_cpu_pct": 2.16
          },
          {
            "t_offset_s": 20.0,
            "total_mem_mib": 56.47,
            "total_cpu_pct": 2.27
          },
          {
            "t_offset_s": 22.0,
            "total_mem_mib": 56.38,
            "total_cpu_pct": 2.26
          },
          {
            "t_offset_s": 24.0,
            "total_mem_mib": 56.4,
            "total_cpu_pct": 2.14
          },
          {
            "t_offset_s": 26.0,
            "total_mem_mib": 56.62,
            "total_cpu_pct": 2.15
          },
          {
            "t_offset_s": 28.1,
            "total_mem_mib": 56.51,
            "total_cpu_pct": 2.07
          },
          {
            "t_offset_s": 30.1,
            "total_mem_mib": 58.63,
            "total_cpu_pct": 3.2
          },
          {
            "t_offset_s": 32.1,
            "total_mem_mib": 58.74,
            "total_cpu_pct": 2.11
          },
          {
            "t_offset_s": 34.1,
            "total_mem_mib": 58.85,
            "total_cpu_pct": 2.3
          },
          {
            "t_offset_s": 36.1,
            "total_mem_mib": 58.7,
            "total_cpu_pct": 2.08
          },
          {
            "t_offset_s": 38.1,
            "total_mem_mib": 58.7,
            "total_cpu_pct": 2.09
          },
          {
            "t_offset_s": 40.1,
            "total_mem_mib": 58.67,
            "total_cpu_pct": 3.17
          },
          {
            "t_offset_s": 42.1,
            "total_mem_mib": 58.66,
            "total_cpu_pct": 2.12
          },
          {
            "t_offset_s": 44.1,
            "total_mem_mib": 58.72,
            "total_cpu_pct": 2.16
          },
          {
            "t_offset_s": 46.1,
            "total_mem_mib": 58.7,
            "total_cpu_pct": 2.14
          },
          {
            "t_offset_s": 48.1,
            "total_mem_mib": 58.7,
            "total_cpu_pct": 2.05
          },
          {
            "t_offset_s": 50.1,
            "total_mem_mib": 58.68,
            "total_cpu_pct": 3.18
          },
          {
            "t_offset_s": 52.1,
            "total_mem_mib": 58.92,
            "total_cpu_pct": 2.15
          },
          {
            "t_offset_s": 54.1,
            "total_mem_mib": 58.91,
            "total_cpu_pct": 2.13
          },
          {
            "t_offset_s": 56.1,
            "total_mem_mib": 58.87,
            "total_cpu_pct": 2.02
          },
          {
            "t_offset_s": 58.1,
            "total_mem_mib": 58.87,
            "total_cpu_pct": 2.11
          },
          {
            "t_offset_s": 60.1,
            "total_mem_mib": 61.04,
            "total_cpu_pct": 2.28
          },
          {
            "t_offset_s": 62.1,
            "total_mem_mib": 60.98,
            "total_cpu_pct": 2.32
          },
          {
            "t_offset_s": 64.1,
            "total_mem_mib": 61.04,
            "total_cpu_pct": 2.28
          },
          {
            "t_offset_s": 66.1,
            "total_mem_mib": 61.0,
            "total_cpu_pct": 2.25
          },
          {
            "t_offset_s": 68.1,
            "total_mem_mib": 60.75,
            "total_cpu_pct": 2.34
          },
          {
            "t_offset_s": 70.1,
            "total_mem_mib": 60.96,
            "total_cpu_pct": 2.34
          },
          {
            "t_offset_s": 72.1,
            "total_mem_mib": 61.2,
            "total_cpu_pct": 2.22
          },
          {
            "t_offset_s": 74.1,
            "total_mem_mib": 60.85,
            "total_cpu_pct": 1.87
          },
          {
            "t_offset_s": 76.1,
            "total_mem_mib": 60.85,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 78.2,
            "total_mem_mib": 60.85,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 80.2,
            "total_mem_mib": 61.06,
            "total_cpu_pct": 11.11
          },
          {
            "t_offset_s": 82.2,
            "total_mem_mib": 61.0,
            "total_cpu_pct": 10.58
          },
          {
            "t_offset_s": 84.2,
            "total_mem_mib": 61.29,
            "total_cpu_pct": 10.46
          },
          {
            "t_offset_s": 86.2,
            "total_mem_mib": 61.15,
            "total_cpu_pct": 10.68
          },
          {
            "t_offset_s": 88.2,
            "total_mem_mib": 61.08,
            "total_cpu_pct": 10.55
          },
          {
            "t_offset_s": 90.2,
            "total_mem_mib": 61.27,
            "total_cpu_pct": 10.61
          },
          {
            "t_offset_s": 92.2,
            "total_mem_mib": 61.2,
            "total_cpu_pct": 10.76
          },
          {
            "t_offset_s": 94.2,
            "total_mem_mib": 61.3,
            "total_cpu_pct": 10.61
          },
          {
            "t_offset_s": 96.2,
            "total_mem_mib": 61.22,
            "total_cpu_pct": 11.71
          },
          {
            "t_offset_s": 98.2,
            "total_mem_mib": 61.37,
            "total_cpu_pct": 11.6
          },
          {
            "t_offset_s": 100.2,
            "total_mem_mib": 61.25,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 102.2,
            "total_mem_mib": 61.11,
            "total_cpu_pct": 0.01
          },
          {
            "t_offset_s": 104.2,
            "total_mem_mib": 61.11,
            "total_cpu_pct": 0.01
          }
        ],
        "series_start_offset_s": 1.5,
        "peak_note": "peak = highest value seen across docker stats samples (about one every 2-3 s); shorter spikes between samples are not seen",
        "peak_memory_stat": {
          "read_at": "2026-10-19T03:26:21Z",
          "per_service": {
            "adguardhome": {
              "cgroup": "v2",
              "anon_mib": 59.73,
              "file_mib": 11.09,
              "active_file_mib": 0.0,
              "inactive_file_mib": 11.09,
              "shmem_mib": 0.0
            }
          },
          "read_lag_s": 0.0,
          "series_index": 49,
          "sample_t_offset_s": 98.2,
          "total_mem_mib": 61.37
        }
      },
      "container_end_state": {
        "adguardhome": {
          "restart_count": 0,
          "oom_killed": false
        }
      },
      "teardown": {
        "done": true,
        "volumes_removed": true,
        "images_removed": false,
        "error": null
      },
      "warnings": [],
      "finished_at": "2026-10-19T03:26:27Z",
      "elapsed_seconds": 259.8
    }
  ],
  "load_defined": true,
  "notes": [
    "Host: a GitHub Actions runner (ubuntu-latest, x86_64, 2 vCPU, 8 GB RAM; the CPU model varies between runners (AMD EPYC and Intel Xeon models so far) and each run records its own). Not a Raspberry Pi: no Arm result, and the numbers are valid for that host only.",
    "Measured: idle RAM and CPU after the wizard and one filter list with no client; RAM and CPU while one client sends the DNS load of load.description (200 queries/s for 60 s, then 1,000 queries/s for 20 s); image size; start-up time; answer latency seen by that client. Not measured: real clients or a real household's query mix, DNS-over-HTTPS or DNS-over-TLS, DHCP, IPv6, DNSSEC, long-term growth of the query log and statistics, filter lists beyond the one, Arm hardware.",
    "Fair comparison: both apps use the same upstream resolver (1.1.1.1, plain UDP), the same single blocklist (StevenBlack unified hosts, Pi-hole's default list) and the same blocking answer (0.0.0.0). The upstream resolver's response time varies from run to run, so the first-time latency (which includes it) is not comparable between runs or apps; the latency of repeated queries that the resolver should answer from its cache is. The script counts a repeat as cache-expected when an earlier answer for that name arrived less than half its TTL ago.",
    "Settings changed from the app's defaults, in setup: upstream 1.1.1.1 plain UDP (default: DNS-over-HTTPS to Quad9), rate limit off (default 20 queries/s per client), DNSSEC flag off (default on), blocking mode null_ip (default: 'default'), the default filters AdGuard DNS filter and AdAway removed and the StevenBlack list added. Left at default: query log and statistics on, cache on at 4 MiB, upstream mode load balancing (one upstream, so no effect).",
    "The 'rules loaded' figure is AdGuard Home's rules_count for the list: it counts a few non-domain lines of the hosts file (localhost entries) that Pi-hole's gravity count leaves out; the two numbers are close but not the same quantity.",
    "Lab-only compose override compose.lab.yaml (NOT in the published compose): The lab run publishes no host ports (53, 80 and 3000 of the published file are not mapped): the runner's systemd-resolved listens on 127.0.0.53:53 and Docker's port 53 publishing can clash with it, and the setup and load steps reach AdGuard Home by service name over the Compose network instead. Image and volumes are the published file's. The published file has not been run with its ports mapped in the lab."
  ],
  "warnings": [],
  "files": {
    "compose": "adguard-home.compose.yaml",
    "env": null
  },
  "definitions": {
    "memory": "cgroup working set as reported by `docker stats` (usage minus inactive file cache), MiB = 2^20 bytes",
    "cpu": "percent of ONE core as reported by `docker stats` (4 busy cores = 400)",
    "total": "stats over the sum of all containers at the same instant",
    "sample_interval": "docker stats --no-stream takes about 1-2 s per call, so samples are 2-3 s apart",
    "runs": "each run is a full fresh cycle (up, health, setup, settle, idle, load, down -v); the published figure is the median over the runs, shown with the min-max range; see summary.rule"
  }
}
