Como Criar Seu Próprio Teste de Velocidade em PHP — Download, Upload e Ping Sem Depender de Terceiros

Criar um teste de velocidade de internet pode parecer algo complexo, mas na prática, é possível fazer tudo com PHP e JavaScript puro, sem bibliotecas externas, sem dependência de terceiros e sem enrolação.

Este post mostra como montar um sistema que mede:

  • Velocidade de download
  • Velocidade de upload
  • Latência de resposta (proxy de ping)

Tudo em um único arquivo PHP.


speedtest.php

Copie e cole o conteúdo abaixo em um arquivo speedtest.php no seu servidor:

<?php
// Backend de upload
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['upload'])) {
    $start = microtime(true);
    file_get_contents('php://input'); // consome os dados enviados
    $time = microtime(true) - $start;
    $size = (int) ($_SERVER['CONTENT_LENGTH'] ?? 0);

    echo json_encode([
        'upload_speed_mbps' => round(($size * 8 / 1024 / 1024) / $time, 2),
        'time' => round($time, 3)
    ]);
    exit;
}

// Backend de download
if (isset($_GET['download'])) {
    $size = 10 * 1024 * 1024; // 10 MB
    header('Content-Type: application/octet-stream');
    header('Content-Length: ' . $size);
    echo str_repeat('A', $size);
    exit;
}
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Teste de Velocidade</title>
    <style>
        body { font-family: monospace; margin: 2rem; }
        button { padding: 0.5rem 1rem; font-size: 1rem; }
        pre { background: #f0f0f0; padding: 1rem; border: 1px solid #ccc; }
    </style>
</head>
<body>
    <h1>Teste de Velocidade</h1>
    <button onclick="runTest()">Iniciar Teste</button>
    <pre id="result">Clique no botão para começar o teste.</pre>

    <script>
    async function runTest() {
        const result = document.getElementById('result');
        result.textContent = "Iniciando teste de download...";

        // Teste de Download
        const startDownload = performance.now();
        const blob = await fetch('?download=1').then(r => r.blob());
        const endDownload = performance.now();
        const downloadTime = (endDownload - startDownload) / 1000;
        const downloadMbps = ((blob.size * 8) / 1024 / 1024) / downloadTime;

        result.textContent = `Download: ${downloadMbps.toFixed(2)} Mbps\nIniciando teste de upload...`;

       // Teste de Upload
        const uploadPayload = new Uint8Array(5 * 1024 * 1024); // 5 MB

        const startUpload = performance.now();
        const uploadResp = await fetch('?upload=1', {
            method: 'POST',
            headers: { 'Content-Type': 'application/octet-stream' },
            body: uploadPayload
        });
        const endUpload = performance.now();
        const uploadData = await uploadResp.json();

        // Ajustando o cálculo do tempo e velocidade do upload
        const uploadTime = (endUpload - startUpload) / 1000; // Tempo em segundos
        const uploadMbps = (uploadPayload.length * 8 / 1024 / 1024) / uploadTime; // Calcula a velocidade de upload

        result.textContent += `\nUpload: ${uploadMbps.toFixed(2)} Mbps`;
        result.textContent += `\nLatência de upload: ${uploadData.time * 1000} ms`;

    }
    </script>
</body>
</html>

Considerações Técnicas

O que isso mede com precisão

  • Download entre cliente e servidor via HTTP (sem cache)
  • Upload real com consumo de 5 MB
  • Tempo de resposta do upload como métrica de latência

O que isso não é

  • Não é um Speedtest.net. Não usa múltiplas conexões TCP paralelas.
  • Não testa sua conexão com a internet como um todo, apenas com o servidor onde está hospedado.

Onde isso é útil

  • Para testar qualidade de conexão com seu servidor
  • Para usar como ferramenta interna em redes, provedores ou intranets
  • Para testar o desempenho entre clientes e servidores em datacenters

Limitações e Expansões

  • É possível usar Web Workers para fazer múltiplas conexões paralelas e simular um Speedtest profissional.
  • Pode-se usar backend em Go, Python ou Node.js se o objetivo for suportar alto tráfego com mais eficiência.
  • Pode-se integrar log, autenticação, fila de testes e estatísticas.
Rolar para cima