この記事でわかること
- WindowsからNASの転送速度を正確に測る方法(PowerShell)
- Tailscale経由とローカル接続で実際どれくらい速度差があるか
- QNAP TS-453D と TS-464 のTailscale経由での実力差
目次
結論から
ローカル接続とTailscale経由では、読み込みで約1.7倍の速度差があります。
また、スペック差があるTS-453DとTS-464でも、Tailscale経由だと差は思ったより小さくなります。
| NAS | 接続方法 | 書き込み(平均) | 読み込み(平均) |
|---|---|---|---|
| TS-464 | ローカル有線 | 67.3 MB/s | 107.0 MB/s |
| TS-464 | Tailscale(VPN) | 61.5 MB/s | 64.7 MB/s |
| TS-453D | Tailscale(VPN) | 51.4 MB/s | 56.3 MB/s |
検証環境
PC
外からの接続を想定して、Wi-Fi接続のノートPC(Intel Wi-Fi 7 BE201)から測定しました。
(測定当日は有線接続が異常に遅かったのでノートPCで測定したのはひみつ。)
| 項目 | 内容 |
|---|---|
| 接続 eo RT150(Z) | Wi-Fi 6(160MHz) |
| 下り(IPv4) | 924.48 Mbps |
| 上り(IPv4) | 587.52 Mbps |
| 下り(IPv6) | 901.86 Mbps |
| 上り(IPv6) | 550.91 Mbps |
NAS(遠隔地設置)
| 項目 | QNAP TS-453D(Wドライブ) | QNAP TS-464(X・Zドライブ) |
|---|---|---|
| CPU | Celeron J4125 | Celeron N5095 |
| RAM | 8GB | 16GB(増設) |
| HDD | Seagate ST6000VN001 × 4本(6TB) | WD Red Plus WD80EFPX × 4本(8TB) |
| キャッシュSSD | なし | Crucial 1TB M.2 PCIe Gen.3 x 1 (1 GB/s) |
| NIC | ※2.5GbE × 2(Balance-alb) | ※2.5GbE × 2(Balance-alb) |
| RAID | RAID5 | RAID5 |
| VPN | Tailscale SMB3 | Tailscale SMB3 |
※接続コネクタはすべて1GbEです。
測定条件
再現性を確保するため、以下の条件を統一しました。
| 条件 | 内容 |
|---|---|
| 測定時間帯 | 平日20〜21時(混雑時間帯) |
| 測定回数 | 各5回・平均値を採用 |
| 測定間隔 | 1回ごとに30秒待機 |
| テストファイル | 1GB固定 |
測定前に停止したNASのサービスは以下のとおりです。これらが動いていると、CPUやメモリを余分に消費して測定値がブレます。
- Qsirch(ファイル検索インデックス)
- Qsync Central
- QNAP AI Core
- Virtualization Station
- HBS 3 Hybrid Backup
- Multimedia Console
測定方法:PowerShellで正確に計測する
自分の環境ではCrystalDiskMarkはネットワークドライブを認識しないため使えませんでした。PowerShellで自前計測します。
なぜWriteThroughが必要か
通常のWriteAllBytesではWindowsのSMBライトキャッシュが効いてしまい、実際の転送速度より高い値が出ます。
実際に比較すると、キャッシュありで74〜77 MB/sと出た数字が、WriteThroughで計測し直すと53 MB/s台まで落ちることがありました。
測定スクリプト(5回自動測定・平均算出)
# ドライブレターをここで指定(W:・X:・Z:など)
$drive = "W:"
$results = @()
for ($i = 1; $i -le 5; $i++) {
Write-Host "=== 測定 $i / 5 ==="
# 書き込み(WriteThroughでキャッシュ排除)
$fs = New-Object System.IO.FileStream(
"$drive\testfile.dat",
[System.IO.FileMode]::Create,
[System.IO.FileAccess]::Write,
[System.IO.FileShare]::None,
8MB,
[System.IO.FileOptions]::WriteThrough
)
$buf = New-Object byte[] (1GB)
$sw = [System.Diagnostics.Stopwatch]::StartNew()
$fs.Write($buf, 0, $buf.Length)
$fs.Flush(); $fs.Close(); $sw.Stop()
$write = [math]::Round(1024 / $sw.Elapsed.TotalSeconds, 1)
Write-Host " 書き込み: $write MB/s"
# メモリキャッシュをクリアしてから読み込み
$buf = $null; [GC]::Collect()
Start-Sleep -Seconds 5
# 読み込み
$sw = [System.Diagnostics.Stopwatch]::StartNew()
$data = [System.IO.File]::ReadAllBytes("$drive\testfile.dat")
$sw.Stop()
$read = [math]::Round(1024 / $sw.Elapsed.TotalSeconds, 1)
Write-Host " 読み込み: $read MB/s"
$results += [PSCustomObject]@{ 回数 = $i; 書き込み = $write; 読み込み = $read }
$data = $null; [GC]::Collect()
Remove-Item "$drive\testfile.dat" -ErrorAction SilentlyContinue
if ($i -lt 5) {
Write-Host " 30秒待機中..."
Start-Sleep -Seconds 30
}
}
# サマリー表示
$results | Format-Table -AutoSize
$avgWrite = [math]::Round(($results.書き込み | Measure-Object -Average).Average, 1)
$avgRead = [math]::Round(($results.読み込み | Measure-Object -Average).Average, 1)
$maxWrite = ($results.書き込み | Measure-Object -Maximum).Maximum
$maxRead = ($results.読み込み | Measure-Object -Maximum).Maximum
$minWrite = ($results.書き込み | Measure-Object -Minimum).Minimum
$minRead = ($results.読み込み | Measure-Object -Minimum).Minimum
Write-Host "書き込み → 平均: $avgWrite 最高: $maxWrite 最低: $minWrite MB/s"
Write-Host "読み込み → 平均: $avgRead 最高: $maxRead 最低: $minRead MB/s"
Xドライブを測るときは1行目を$drive = "X:"に変えるだけです。
測定結果
生データ
TS-464 ローカル有線(Zドライブ)
| 回数 | 書き込み | 読み込み |
|---|---|---|
| 1 | 74.5 MB/s | 105.7 MB/s |
| 2 | 59.6 MB/s | 108.1 MB/s |
| 3 | 73.2 MB/s | 107.9 MB/s |
| 4 | 68.5 MB/s | 107.8 MB/s |
| 5 | 60.9 MB/s | 105.4 MB/s |
| 平均 | 67.3 MB/s | 107.0 MB/s |

TS-453D Tailscale経由(Wドライブ)
| 回数 | 書き込み | 読み込み |
|---|---|---|
| 1 | 23.1 MB/s | 49.9 MB/s |
| 2 | 60.0 MB/s | 56.7 MB/s |
| 3 | 60.2 MB/s | 58.9 MB/s |
| 4 | 57.5 MB/s | 60.4 MB/s |
| 5 | 56.1 MB/s | 55.8 MB/s |
| 平均 | 51.4 MB/s | 56.3 MB/s |

TS-464 Tailscale経由(Xドライブ)
| 回数 | 書き込み | 読み込み |
|---|---|---|
| 1 | 63.3 MB/s | 64.3 MB/s |
| 2 | 68.4 MB/s | 63.0 MB/s |
| 3 | 60.8 MB/s | 67.4 MB/s |
| 4 | 57.8 MB/s | 59.2 MB/s |
| 5 | 57.2 MB/s | 69.4 MB/s |
| 平均 | 61.5 MB/s | 64.7 MB/s |

考察
① ローカル vs Tailscale:読み込みで約1.7倍の差
TS-464で比較すると、ローカル接続では読み込み107 MB/sに対して、Tailscale経由では64.7 MB/s。約1.65倍の差が出ました。
書き込みはローカル67.3 MB/s に対してTailscale61.5 MB/sとほぼ同等です。読み込みに差が出やすい理由は、受信データの復号処理がNAS側のCPUに依存しているからなのかも。

↑負荷はかかってはいるものの、ボトルネックにはなっていないと思う。。。
② TS-453D vs TS-464:Tailscaleが性能差を均す
スペック上はCPU・RAMどちらもTS-464が上回りますが、Tailscale経由での差は予想より小さい結果になりました。
| 指標 | TS-453D | TS-464 | 差 |
|---|---|---|---|
| 書き込み平均 | 51.4 MB/s | 61.5 MB/s | +10.1 MB/s |
| 読み込み平均 | 56.3 MB/s | 64.7 MB/s | +8.4 MB/s |
Tailscaleの暗号化処理がどちらのNASでも一定の天井を作っており、ハードウェアスペックの差が出にくくなっているのかも。
③ TS-453Dの書き込み1回目が23.1 MB/sと異様に遅い
2〜5回目は56〜60 MB/s台で安定しているのに、1回目だけ23.1 MB/sと半分以下。スピンアップとかの準備で計測が遅くなったのか、ちょっとわからなかった。
複数回測定して平均を取る重要性。
実用上の評価
いまのTailscale経由(読み込み約56〜65 MB/s)で実際の使い勝手はどうかなー。
| 用途 | 判定 |
|---|---|
| 4K動画ストリーミング(約50Mbps) | 余裕 |
| バックアップ(1TB) | 約4〜5時間(寝る前放置で問題ない) |
| 写真・文書の日常アクセス | 大丈夫 |
| 大量の小ファイル転送 | シーケンシャルより大幅に遅くなる |
まとめ
- PowerShell+WriteThroughで正確に測る
- ローカルとTailscale経由では読み込みで約1.7倍くらい速度差がある
- TS-453DとTS-464のTailscale経由での差は書き込み・読み込みともに約10 MB/s程度
- Tailscaleが性能の天井を作るため、ハードウェアスペック差が出にくいかも
- 1回目の測定値は当てにならないから、必ず複数回測定して平均を取る
Tailscale経由のNASアクセスで「なんか遅い」と感じたときは、まずPowerShellで数字を出して、NAS管理画面のリソースモニターと合わせて確認してみてください。
感想
全部SSDにしたら数値変わるのかーとか、Tailscaleの限界なのかなーとか。CPUがボトルネックになっていたかはわからん!
でも十分すぎる!OpenVPNよりめちゃくちゃ速い!!やったね!!!
今回はやさしめに測ったので厳密に数時間おきにとか、いろんな事象とか用意した訳では無いで、軽く参考までに。
※ 測定値は実機による実測です。回線状況・NASの設定・時間帯によって結果は変わります。
※ 測定時間帯:平日20〜21時。不要なサービスを停止した状態での計測です。
