BytePane
Tools

URL Shortener: Shorten Long URLs for Free

17 min read

Key Takeaways

  • • Bitly hit 10 billion monthly digital connections and surpassed $100M ARR in 2022; the URL shortener market is valued at $490M in 2025 per Business Research Insights
  • • 301 redirects pass ~99% of link equity to the destination; 302 redirects pass zero — use the right one
  • • Base62 encoding with a 7-character slug produces 3.5 trillion unique combinations — sufficient for most large-scale deployments
  • • 28% of campaigns using popular URL shorteners delivered malware per Cofense Intelligence (2024–2025) — hidden destinations are a genuine threat
  • • p99 redirect latency target is under 50ms; sub-millisecond with Redis caching; browser-cached 301s add zero round-trip latency

A product launch email to 50,000 subscribers. The CTA button links to a UTM-tagged URL that's 340 characters long: https://store.example.com/products/widget-pro?utm_source=email&utm_medium=newsletter&utm_campaign=spring2026&utm_content=hero-cta&ref=homepage. That URL will break in plain-text email clients, fail in SMS, and look suspicious in previews. The solution is a URL shortener — but choosing the wrong redirect type, the wrong provider, or no abuse protection can create real problems for SEO, security, and analytics.

This guide covers how URL shorteners work from the HTTP layer down, what to look for in a service, the real security risks, and how to implement a minimal shortener yourself. Let's start with the part most tutorials get wrong: the redirect status code.

301 vs 302 vs 307 vs 308: Which Redirect Code Should You Use?

This is the decision that has the most downstream impact on SEO and analytics — and many shorteners get it wrong by default.

CodeTypeBrowser Caches?Passes Link Equity?Method Preserved?Use When
301PermanentYes~99%No (POST→GET)Stable links, SEO pass-through
302TemporaryNo0%No (POST→GET)A/B testing, changing destinations
307Temp (strict)No0%YesPOST-preserving temp redirect
308Permanent (strict)Yes~99%YesAPI endpoint migrations

The critical point about 301s: once a browser caches the redirect, subsequent clicks never hit the shortener server. The redirect resolves entirely in the browser. This is great for performance (zero additional latency after first visit) but means analytics events on the shortener server are undercounted. Bitly's client-side click tracking injects a brief intermediate page specifically to capture analytics before issuing the final redirect.

Google clarified in 2016 that properly implemented 301 redirects pass effectively 100% of PageRank to the destination — a correction from the earlier ~85% estimate that had been passed around since the PageRank era. Prior to that clarification, shortlinks had a minor SEO penalty; they don't anymore. See our HTTP status codes reference for the full taxonomy of redirect codes and their semantics.

How Slug Generation Works: Base62 and Alternatives

The slug is the unique identifier appended to the short domain: the abc123 in bit.ly/abc123. How it's generated determines the uniqueness capacity and predictability of your URL space.

Base62 Encoding (Industry Standard)

The most robust approach: auto-increment an integer primary key in your database, then encode it in Base62 (characters: a-z A-Z 0-9).

const BASE62_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
const BASE = 62

function encodeBase62(num: number): string {
  if (num === 0) return BASE62_CHARS[0]
  let result = ''
  while (num > 0) {
    result = BASE62_CHARS[num % BASE] + result
    num = Math.floor(num / BASE)
  }
  return result
}

function decodeBase62(slug: string): number {
  let result = 0
  for (const char of slug) {
    result = result * BASE + BASE62_CHARS.indexOf(char)
  }
  return result
}

// Capacity by slug length:
// 6 chars: 62^6 = 56.8 billion unique slugs
// 7 chars: 62^7 = 3.52 trillion unique slugs
// 8 chars: 62^8 = 218 trillion unique slugs

console.log(encodeBase62(1))        // 'b'
console.log(encodeBase62(62))       // 'ba'
console.log(encodeBase62(1000000))  // '4c92'

The strength of this approach: no collision checking needed, decode is O(n) and gives you the database row directly, and the sequence is non-predictable (because Base62 encoding of sequential integers produces non-sequential-looking slugs). The weakness: sequential IDs can be enumerated by incrementing — consider XOR-shuffling IDs before encoding if enumeration is a concern.

Random Generation with Collision Retry

import { randomBytes } from 'crypto'

function generateSlug(length = 7): string {
  // Use crypto.randomBytes — never Math.random() for slugs
  const bytes = randomBytes(length)
  let slug = ''
  for (const byte of bytes) {
    // Map to Base62 character space (rejection sampling)
    const idx = byte % 62
    slug += BASE62_CHARS[idx]
  }
  return slug
}

// In your database layer:
async function createShortURL(longUrl: string): Promise<string> {
  for (let attempts = 0; attempts < 5; attempts++) {
    const slug = generateSlug(7)
    try {
      await db.insert({ slug, url: longUrl })
      return slug
    } catch (err) {
      if (err.code === 'UNIQUE_VIOLATION') continue // retry
      throw err
    }
  }
  throw new Error('Failed to generate unique slug after 5 attempts')
}

At 7 characters and 62^7 ≈ 3.5 trillion combinations, collision probability is negligible until you reach hundreds of billions of stored URLs. At Bitly's scale (256+ million links created monthly), they use Base62 on distributed sequence counters with sharded ID generators to avoid sequential enumeration.

The System Design: Building a URL Shortener at Scale

A URL shortener is a classic system design interview problem because it deceptively simple write path (one INSERT) combined with an extremely hot read path (every shortened link click is a read). At 35,000 QPS, a direct PostgreSQL query per redirect will collapse under load. The production architecture layers caching:

# Request flow for a redirect (read path):
# 1. Browser hits https://sho.rt/abc123
# 2. Edge (CDN) → check CDN cache for slug 'abc123'
#    HIT: return 301 response immediately (~2ms)
#    MISS: forward to origin
# 3. Origin app → check Redis cache for slug
#    HIT: return 301, set CDN cache header (~5ms)
#    MISS: query PostgreSQL, populate Redis, return 301 (~15ms)
# 4. Async analytics event written to Kafka/queue (non-blocking)

# Redis schema for URL mappings:
# SET url:abc123 "https://example.com/very/long/url" EX 86400
# Key includes TTL so stale entries self-evict

# Write path:
# 1. Validate URL (scheme, length, malware check)
# 2. Generate slug via Base62 encoded sequence ID
# 3. INSERT into PostgreSQL (source of truth)
# 4. Populate Redis cache
# 5. Return short URL to user

With Redis in front of the database, a production shortener can achieve sub-millisecond lookup times and sustain 100,000+ QPS on commodity hardware. Bitly's enterprise SLA guarantees 99.9% uptime with measured p99 redirect latency under 50ms globally.

URL encoding matters here too: long URLs must be properly percent-encoded before storage. Use our URL encoder/decoder tool to inspect and fix malformed URLs, or see the URL encoding guide for the full spec on when and why to encode.

The Security Problem Nobody Talks About

In July 2024 through June 2025, Cofense Intelligence analyzed phishing campaigns targeting enterprise email users. Their finding: 28% of campaigns using popular URL shorteners delivered malware. The mechanism is straightforward — attackers register legitimate shortened links pointing to clean content, get them past email security scanners, then redirect to malware payloads after the scan.

Menlo Security documented a 198% increase in browser-based phishing attacks over a six-month period, with URL shorteners as a primary evasion vector. Traditional URL filtering tools score the shortener's domain reputation (bit.ly = safe), not the destination — making detection nearly impossible without following the redirect chain.

Palo Alto Unit 42 found a 55% increase in QR code shortener traffic from H1 2023 to H1 2024, and a further 44% increase in the following year — QR codes being another way attackers use shorteners to obscure destinations from scanners.

Defensive Measures When Building a Shortener

  • Safe Browsing API check: Google's Safe Browsing API (free up to 10,000 req/day) flags known malware/phishing URLs before you shorten them
  • Follow redirects before storing: If the destination URL is itself a redirect chain, resolve it fully and store the final target for transparency
  • Rate limiting by IP: Bulk link creation from a single IP is a clear abuse signal; limit to 100 creations/hour for unauthenticated users
  • Preview pages: Bitly appends + to a slug to show a preview page; implement the same pattern so security-conscious users can inspect the destination
  • Takedown mechanism: Build an admin endpoint to immediately deactivate a slug and replace it with a warning page

URL Shortener Services Compared

ServiceFree TierCustom DomainAnalyticsBest For
TinyURLYes, unlimitedPaid onlyMinimalQuick one-off links (est. 2002, 104M visits/mo)
Bitly10 links/moYes (paid)Deep analyticsEnterprise campaigns, 10B monthly connections
Rebrandly5 links/moMultiple domainsYesBranded links, teams
Short.io1K clicks/moYesReal-timeDevelopers, webhook/API integration
ShlinkFree (self-hosted)YesFull controlNo vendor lock-in, privacy-first

Bitly is the clear market leader: 500,000+ global customers, 5.7 million monthly active users, 256+ million links created monthly, and $100M ARR crossed in 2022 per Bitly's own press releases. TinyURL, despite minimal features, attracted 104 million website visits in October 2025 alone (per SemRush data) — a testament to the enduring power of “first mover in a simple utility.”

Google shut down goo.gl in 2019. Ow.ly (Hootsuite) remains but is tightly coupled to their social platform. The global URL shortener market was valued at approximately $490 million in 2025 and is projected to reach $2.55 billion by 2034 at a ~20% CAGR per Business Research Insights.

Analytics and Tracking: What Shorteners Measure

A URL shortener is fundamentally a measurement layer on top of a redirect. Modern services track:

  • Total clicks vs unique clicks: Total counts every redirect; unique deduplicates by IP + User-Agent within a time window
  • Geographic distribution: Country and city breakdown using IP geolocation (see accuracy caveats above)
  • Device and browser: Parsed from User-Agent string
  • Referrer: The HTTP Referer header revealing whether the click came from Twitter, a newsletter, direct, etc.
  • Time series: Click volume over time, useful for measuring campaign decay

According to a U.S. Department of Commerce 2023 survey, 38% of businesses connect URL shorteners with analytics tools to monitor campaign performance. Per Bitly, 95% of B2B marketers use short links in their campaigns, with 65% of URL shortener market growth driven by social media campaigns where link length is constrained.

UTM parameters survive the redirect intact — the shortener stores the full destination URL including query strings. UTM-tagged links like ?utm_source=email&utm_medium=newsletter pass through to Google Analytics as-is, letting you attribute conversions correctly.

Building Your Own URL Shortener: Minimal Implementation

A production-viable URL shortener in Node.js/Express fits in approximately 80 lines of code for the core logic:

import express from 'express'
import { Pool } from 'pg'
import { createClient } from 'redis'
import { URL } from 'url'

const app = express()
app.use(express.json())

const db = new Pool({ connectionString: process.env.DATABASE_URL })
const redis = createClient({ url: process.env.REDIS_URL })
await redis.connect()

const BASE62 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
function toBase62(n: number): string {
  let s = ''
  while (n > 0) { s = BASE62[n % 62] + s; n = Math.floor(n / 62) }
  return s || '0'
}

// POST /shorten — create a short link
app.post('/shorten', async (req, res) => {
  const { url } = req.body
  // Validate URL scheme (reject javascript:, data:, etc.)
  try {
    const parsed = new URL(url)
    if (!['http:', 'https:'].includes(parsed.protocol)) {
      return res.status(400).json({ error: 'Only http/https URLs allowed' })
    }
  } catch {
    return res.status(400).json({ error: 'Invalid URL' })
  }

  const result = await db.query(
    'INSERT INTO urls (long_url) VALUES ($1) RETURNING id',
    [url]
  )
  const slug = toBase62(result.rows[0].id)
  await redis.set(`url:${slug}`, url, { EX: 86400 }) // 24h cache
  res.json({ short: `https://sho.rt/${slug}` })
})

// GET /:slug — redirect
app.get('/:slug', async (req, res) => {
  const { slug } = req.params
  if (!/^[a-zA-Z0-9]{1,10}$/.test(slug)) {
    return res.status(400).send('Invalid slug')
  }

  // Try Redis cache first
  let longUrl = await redis.get(`url:${slug}`)
  if (!longUrl) {
    // Fall back to database
    const id = slug.split('').reduce((n, c) => n * 62 + BASE62.indexOf(c), 0)
    const row = await db.query('SELECT long_url FROM urls WHERE id = $1', [id])
    if (!row.rows[0]) return res.status(404).send('Not found')
    longUrl = row.rows[0].long_url
    await redis.set(`url:${slug}`, longUrl, { EX: 86400 })
  }

  // 301 for stable links; use 302 if destination can change
  res.redirect(301, longUrl)
})

app.listen(3000)

Note the slug validation regex on line 46: /^[a-zA-Z0-9]{1,10}$/. This is critical to prevent path traversal and injection attacks. Never pass user-supplied slugs directly to a database query without validation. Use our regex tester to verify your slug validation pattern, and see the URL validation patterns guide for production-ready URL format checking before storage.

Custom Domains and Branded Short Links

A branded short domain (e.g., go.brand.com/campaign instead of bit.ly/xyz123) increases click-through rates by 25–35% per Rebrandly's internal data across millions of links — users trust links from recognizable domains. Bitly supports custom domains on paid plans; Rebrandly is built specifically for multi-domain branded link management.

For self-hosted implementations, custom domain support requires: a wildcard DNS record pointing to your server, wildcard SSL certificate (Let's Encrypt supports this with DNS-01 challenge), and a multi-tenant domain routing layer in your application that maps incoming hostnames to link spaces.

The DNS configuration involves a CNAME record on the custom domain pointing to your shortener infrastructure. Use our DNS records guide if you need a refresher on CNAME vs A record for this setup.

Encode and Decode URLs Instantly

Before storing long URLs in a shortener database, make sure they're properly percent-encoded. Use BytePane's URL encoder to inspect and fix malformed URLs.

Open URL Encoder / Decoder

Frequently Asked Questions

Do URL shorteners hurt SEO?

No, when configured correctly. A 301 (permanent) redirect passes approximately 99% of link equity to the destination, per Google's guidance from 2016. 302 redirects pass zero link equity — avoid for permanent links. Redirect chains (shortlink → another redirect → destination) lose equity at each hop, so keep it to one redirect step.

What is the difference between 301 and 302 redirects?

301 (Permanent Redirect) is cached by browsers — subsequent visits skip the shortener server entirely — and passes full link equity. 302 (Temporary Redirect) checks the server on every click, passes no link equity, and is ideal when the destination URL may change (e.g., A/B testing). Most shorteners use 301 by default for stable links.

Are URL shorteners safe to click?

URL shorteners hide the destination, which bad actors exploit. According to Cofense Intelligence (2024–2025 data), 28% of campaigns using popular URL shorteners delivered malware. Safe practices: use Bitly's preview feature (append + to the URL), hover to see URLs in desktop clients, and treat unsolicited shortened links with the same caution as email attachments.

How are short URL slugs generated?

The most common approach is Base62 encoding: an auto-incrementing integer is encoded using 62 characters (a–z, A–Z, 0–9). A 7-character Base62 slug yields 627 ≈ 3.5 trillion unique combinations. Alternatives include cryptographically random strings with collision retry, and MD5 hash prefix (collision-prone at scale).

What is the redirect latency of URL shorteners?

Industry-standard p99 target is under 50ms for redirect resolution. Real-world averages are around 300ms (±150ms) depending on geography and cache state. With distributed Redis caching, lookups can be sub-millisecond. 301-cached links (after first visit) resolve instantly in the browser with no additional network round-trip.

Can you build your own URL shortener?

Yes. A basic shortener needs: a database (PostgreSQL or Redis) to store slug → long URL mappings, a Base62 encoder for slug generation, and a redirect handler issuing 301 responses. A minimal Node.js implementation fits under 80 lines. For production, add rate limiting, Safe Browsing API checks, analytics logging, and custom domain support.

Related Articles