- Encurtar URL longa → retorna URL curta
- Redirecionar: quando acessa URL curta → vai para longa
- Deletar URL curta
- 100M URLs criadas/mês
- 1B redirecionamentos/mês
- Latência < 100ms (especialmente redirecionamento)
- 99.99% uptime
- 1 milhão de usuários ativos/dia
- 100 tweets/segundo (TPS)
- Armazenamento: 100GB/dia
- Largura de banda: 50MB/s
// Criar URL curta
POST /shorten
{
"long_url": "https://www.example.com/very/long/url"
}
Response: { "short_url": "https://short.ly/abc123" }
// Redirecionar
GET /abc123
Response: 301 redirect para https://www.example.com/very/long/url
// Deletar
DELETE /abc123
Response: 204 No Content
// Estatísticas (opcional)
GET /abc123/stats
Response: { "clicks": 5000, "created_at": "...", ... }
[Cliente quer encurtar URL]
↓
[Load Balancer]
↓
[API Servers] (encurtamento)
↓
[Redis Cache] ← armazena mapeamento short_code → long_url
↓
[MySQL] ← BD persistente
[Cliente acessa short.ly/abc123]
↓
[CDN/Cache Layer] ← MUITO RÁPIDO (crítico!)
↓ (se não estiver em cache)
[Redirect Service]
↓
[Redis]
↓
[MySQL]
-- Tabela principal
CREATE TABLE shortened_urls (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
short_code VARCHAR(10) UNIQUE NOT NULL, -- "abc123"
long_url VARCHAR(2048) NOT NULL, -- URL original
user_id INT, -- Quem criou
created_at TIMESTAMP,
expires_at TIMESTAMP,
is_deleted BOOLEAN DEFAULT FALSE,
INDEX(short_code), -- Busca rápida por código curto
INDEX(user_id) -- Busca URLs de um usuário
);
-- Tabela de cliques (opcional)
CREATE TABLE clicks (
id BIGINT PRIMARY KEY,
short_url_id BIGINT,
clicked_at TIMESTAMP,
user_ip VARCHAR(45),
user_agent TEXT,
INDEX(short_url_id, clicked_at)
);
Component 1: Como gerar código curto (abc123)?
// Opção 1: Base62 encoding
function generateShortCode(id) {
const base62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
let code = ''
while (id > 0) {
code = base62[id % 62] + code
id = Math.floor(id / 62)
}
return code
}
// ID 1 → "1"
// ID 62 → "10"
// ID 3844 → "100"
Component 2: Cache Strategy
Quando usuário encurta:
1. Gera código curto
2. Armazena em BD
3. Armazena em Cache: "abc123" → "https://example.com/..."
4. TTL = 24 horas (ou até expirar)
Quando usuário acessa:
1. Procura em Cache (Redis) ← RÁPIDO
2. Se não tiver, procura em BD
3. Redireciona (301 permanente)
4. Log de clique (async, não bloqueia)
Component 3: Escalabilidade
- Múltiplos API Servers
- Cache distribuído (Redis Cluster)
- BD replicada (master-slave)
- CDN para cache geográfica
- Sharding por usuário_id (se BD fica muito grande)